From f78b9190923f7c5890089a7c0e19325244877639 Mon Sep 17 00:00:00 2001 From: Inseok Lee Date: Sun, 16 Aug 2026 20:31:20 +0900 Subject: [PATCH 1/2] Fix virtual method dispatch resolution --- .../classes/java/io/buffered_input_stream.rs | 16 +- .../classes/java/io/buffered_output_stream.rs | 10 +- .../src/classes/java/io/buffered_reader.rs | 16 +- .../src/classes/java/io/buffered_writer.rs | 17 +- .../java/io/byte_array_output_stream.rs | 3 +- .../src/classes/java/io/char_array_writer.rs | 12 +- .../src/classes/java/io/data_input_stream.rs | 23 +- .../src/classes/java/io/data_output_stream.rs | 43 +- java_runtime/src/classes/java/io/file.rs | 28 +- .../src/classes/java/io/file_input_stream.rs | 2 +- .../src/classes/java/io/file_output_stream.rs | 2 +- .../classes/java/io/filter_input_stream.rs | 42 +- .../classes/java/io/filter_output_stream.rs | 24 +- .../src/classes/java/io/input_stream.rs | 33 +- .../classes/java/io/input_stream_reader.rs | 8 +- .../src/classes/java/io/output_stream.rs | 6 +- .../classes/java/io/output_stream_writer.rs | 23 +- .../src/classes/java/io/print_stream.rs | 101 +- .../src/classes/java/io/print_writer.rs | 86 +- .../src/classes/java/io/random_access_file.rs | 47 +- java_runtime/src/classes/java/io/reader.rs | 32 +- .../src/classes/java/io/string_reader.rs | 6 +- .../src/classes/java/io/string_writer.rs | 25 +- java_runtime/src/classes/java/io/writer.rs | 45 +- .../java/lang/abstract_string_builder.rs | 144 +- java_runtime/src/classes/java/lang/boolean.rs | 8 +- java_runtime/src/classes/java/lang/byte.rs | 28 +- .../src/classes/java/lang/character.rs | 16 +- java_runtime/src/classes/java/lang/class.rs | 20 +- .../src/classes/java/lang/class_loader.rs | 92 +- java_runtime/src/classes/java/lang/double.rs | 30 +- java_runtime/src/classes/java/lang/enum.rs | 3 +- java_runtime/src/classes/java/lang/float.rs | 30 +- java_runtime/src/classes/java/lang/integer.rs | 20 +- java_runtime/src/classes/java/lang/long.rs | 18 +- java_runtime/src/classes/java/lang/math.rs | 2 +- java_runtime/src/classes/java/lang/number.rs | 4 +- java_runtime/src/classes/java/lang/object.rs | 48 +- java_runtime/src/classes/java/lang/short.rs | 16 +- java_runtime/src/classes/java/lang/string.rs | 100 +- .../src/classes/java/lang/string_buffer.rs | 173 +- .../src/classes/java/lang/string_builder.rs | 4 +- java_runtime/src/classes/java/lang/system.rs | 10 +- java_runtime/src/classes/java/lang/thread.rs | 31 +- .../src/classes/java/lang/throwable.rs | 93 +- .../classes/java/net/jar_url_connection.rs | 53 +- java_runtime/src/classes/java/net/url.rs | 18 +- .../src/classes/java/net/url_class_loader.rs | 41 +- .../src/classes/java/net/url_connection.rs | 10 +- .../classes/java/net/url_stream_handler.rs | 17 +- .../src/classes/java/text/date_format.rs | 23 +- .../src/classes/java/text/decimal_format.rs | 99 +- java_runtime/src/classes/java/text/format.rs | 11 +- .../src/classes/java/text/number_format.rs | 26 +- .../classes/java/text/simple_date_format.rs | 66 +- .../classes/java/util/abstract_collection.rs | 147 +- .../src/classes/java/util/abstract_list.rs | 118 +- .../java/util/abstract_list_sub_list.rs | 87 +- .../src/classes/java/util/abstract_map.rs | 178 +- .../src/classes/java/util/abstract_set.rs | 28 +- .../src/classes/java/util/array_list.rs | 53 +- .../src/classes/java/util/array_list_itr.rs | 36 +- java_runtime/src/classes/java/util/arrays.rs | 15 +- .../src/classes/java/util/calendar.rs | 92 +- .../src/classes/java/util/collections.rs | 151 +- .../java/util/collections_copies_list.rs | 32 +- .../java/util/collections_empty_list.rs | 2 +- .../java/util/collections_empty_set.rs | 5 +- .../java/util/collections_singleton_set.rs | 28 +- .../collections_unmodifiable_collection.rs | 51 +- ...ctions_unmodifiable_collection_iterator.rs | 6 +- .../util/collections_unmodifiable_list.rs | 32 +- .../collections_unmodifiable_list_iterator.rs | 18 +- .../java/util/collections_unmodifiable_map.rs | 38 +- .../collections_unmodifiable_map_entry.rs | 44 +- .../collections_unmodifiable_map_entry_set.rs | 57 +- ...ons_unmodifiable_map_entry_set_iterator.rs | 7 +- .../java/util/collections_unmodifiable_set.rs | 5 +- .../collections_unmodifiable_sorted_map.rs | 33 +- .../collections_unmodifiable_sorted_set.rs | 33 +- .../src/classes/java/util/formatter.rs | 68 +- .../classes/java/util/gregorian_calendar.rs | 17 +- .../src/classes/java/util/hash_map.rs | 38 +- .../src/classes/java/util/hash_map_entry.rs | 18 +- .../classes/java/util/hash_map_entry_set.rs | 36 +- .../src/classes/java/util/hash_map_key_set.rs | 18 +- .../src/classes/java/util/hash_map_values.rs | 38 +- .../src/classes/java/util/hash_set.rs | 28 +- .../src/classes/java/util/hashtable.rs | 156 +- .../src/classes/java/util/hashtable_entry.rs | 18 +- .../classes/java/util/hashtable_entry_set.rs | 33 +- .../classes/java/util/hashtable_key_set.rs | 15 +- .../src/classes/java/util/hashtable_values.rs | 23 +- .../illegal_format_conversion_exception.rs | 4 +- .../src/classes/java/util/jar/attributes.rs | 18 +- .../src/classes/java/util/jar/jar_file.rs | 30 +- .../classes/java/util/jar/jar_file_entries.rs | 7 +- .../src/classes/java/util/jar/manifest.rs | 18 +- .../src/classes/java/util/linked_hash_map.rs | 42 +- .../linked_hash_map_linked_hash_iterator.rs | 8 +- .../src/classes/java/util/linked_list.rs | 14 +- .../src/classes/java/util/linked_list_itr.rs | 30 +- .../classes/java/util/logging/formatter.rs | 12 +- .../src/classes/java/util/logging/handler.rs | 22 +- .../classes/java/util/logging/log_manager.rs | 68 +- .../src/classes/java/util/logging/logger.rs | 110 +- .../java/util/logging/simple_formatter.rs | 37 +- .../java/util/logging/stream_handler.rs | 63 +- .../src/classes/java/util/properties.rs | 109 +- java_runtime/src/classes/java/util/random.rs | 26 +- .../src/classes/java/util/regex/matcher.rs | 124 +- .../src/classes/java/util/regex/pattern.rs | 91 +- .../util/regex/pattern_syntax_exception.rs | 56 +- java_runtime/src/classes/java/util/stack.rs | 54 +- .../src/classes/java/util/string_tokenizer.rs | 19 +- .../src/classes/java/util/time_zone.rs | 8 +- java_runtime/src/classes/java/util/timer.rs | 8 +- .../src/classes/java/util/timer_thread.rs | 8 +- .../src/classes/java/util/tree_map.rs | 54 +- .../src/classes/java/util/tree_map_entry.rs | 18 +- .../classes/java/util/tree_map_entry_set.rs | 70 +- .../src/classes/java/util/tree_map_key_set.rs | 26 +- .../src/classes/java/util/tree_map_sub_map.rs | 62 +- .../src/classes/java/util/tree_map_values.rs | 30 +- .../src/classes/java/util/tree_set.rs | 76 +- java_runtime/src/classes/java/util/vector.rs | 214 +- .../src/classes/java/util/vector_itr.rs | 30 +- .../src/classes/java/util/zip/zip_file.rs | 23 +- .../classes/java/util/zip/zip_file_entries.rs | 8 +- .../rustjava/lang/rust_jar_class_loader.rs | 15 +- .../org/rustjava/net/file_url_connection.rs | 8 +- .../org/rustjava/net/file_url_handler.rs | 5 +- .../org/rustjava/net/jar_url_connection.rs | 45 +- .../org/rustjava/net/jar_url_handler.rs | 3 +- .../classes/java/io/test_buffered_reader.rs | 245 ++- .../classes/java/io/test_buffered_streams.rs | 297 ++- .../java/io/test_byte_array_input_stream.rs | 20 +- .../java/io/test_byte_array_output_stream.rs | 78 +- .../classes/java/io/test_char_streams.rs | 253 ++- .../classes/java/io/test_data_input_stream.rs | 98 +- .../java/io/test_data_output_stream.rs | 175 +- .../classes/java/io/test_file_input_stream.rs | 17 +- .../java/io/test_file_reader_writer.rs | 103 +- .../java/io/test_input_stream_reader.rs | 102 +- .../java/io/test_output_stream_close.rs | 28 +- .../java/io/test_output_stream_writer.rs | 34 +- .../classes/java/io/test_print_stream.rs | 302 ++- .../classes/java/io/test_print_writer.rs | 261 ++- .../java/io/test_random_access_file.rs | 4 +- .../classes/java/io/test_stream_locking.rs | 84 +- .../classes/java/io/test_string_writer.rs | 63 +- .../tests/classes/java/lang/test_boolean.rs | 80 +- .../tests/classes/java/lang/test_byte.rs | 101 +- .../tests/classes/java/lang/test_character.rs | 62 +- .../tests/classes/java/lang/test_class.rs | 287 ++- .../java/lang/test_cldc11_exceptions.rs | 4 +- .../tests/classes/java/lang/test_double.rs | 180 +- .../tests/classes/java/lang/test_float.rs | 159 +- .../tests/classes/java/lang/test_integer.rs | 95 +- .../tests/classes/java/lang/test_long.rs | 96 +- .../tests/classes/java/lang/test_number.rs | 50 +- .../tests/classes/java/lang/test_object.rs | 52 +- .../tests/classes/java/lang/test_short.rs | 87 +- .../tests/classes/java/lang/test_string.rs | 1093 +++++++-- .../classes/java/lang/test_string_buffer.rs | 749 +++++-- .../classes/java/lang/test_string_builder.rs | 42 +- .../tests/classes/java/lang/test_system.rs | 7 +- .../tests/classes/java/lang/test_thread.rs | 124 +- .../tests/classes/java/lang/test_throwable.rs | 54 +- .../java/net/test_jar_url_connection.rs | 40 +- .../classes/java/net/test_url_class_loader.rs | 81 +- .../classes/java/text/test_date_format.rs | 195 +- .../tests/classes/java/text/test_format.rs | 108 +- .../classes/java/text/test_number_format.rs | 264 ++- .../classes/java/util/jar/test_attributes.rs | 9 +- .../classes/java/util/jar/test_jar_file.rs | 60 +- .../classes/java/util/jar/test_manifest.rs | 16 +- .../java/util/logging/test_handlers.rs | 77 +- .../classes/java/util/logging/test_level.rs | 16 +- .../java/util/logging/test_log_record.rs | 62 +- .../classes/java/util/logging/test_logger.rs | 111 +- .../classes/java/util/regex/test_matcher.rs | 498 ++++- .../classes/java/util/regex/test_pattern.rs | 103 +- .../regex/test_pattern_syntax_exception.rs | 96 +- .../java/util/regex/test_replacement.rs | 168 +- .../classes/java/util/regex/test_split.rs | 40 +- .../classes/java/util/test_array_list.rs | 372 +++- .../tests/classes/java/util/test_arrays.rs | 260 ++- .../java/util/test_collection_contracts.rs | 1205 ++++++++-- .../classes/java/util/test_collections.rs | 1948 ++++++++++++++--- .../tests/classes/java/util/test_date.rs | 112 +- .../tests/classes/java/util/test_formatter.rs | 180 +- .../java/util/test_gregorian_calendar.rs | 144 +- .../tests/classes/java/util/test_hash_map.rs | 763 +++++-- .../tests/classes/java/util/test_hash_set.rs | 220 +- .../tests/classes/java/util/test_hashtable.rs | 384 +++- .../classes/java/util/test_linked_hash_map.rs | 283 ++- .../classes/java/util/test_list_views.rs | 864 ++++++-- .../tests/classes/java/util/test_locale.rs | 118 +- .../classes/java/util/test_properties.rs | 256 ++- .../tests/classes/java/util/test_random.rs | 155 +- .../tests/classes/java/util/test_stack.rs | 126 +- .../java/util/test_string_tokenizer.rs | 141 +- .../tests/classes/java/util/test_timer.rs | 239 +- .../tests/classes/java/util/test_timezone.rs | 131 +- .../tests/classes/java/util/test_tree_map.rs | 1847 +++++++++++++--- .../tests/classes/java/util/test_url.rs | 14 +- .../tests/classes/java/util/test_vector.rs | 580 ++++- .../classes/java/util/zip/test_zip_file.rs | 22 +- .../lang/test_rust_jar_class_loader.rs | 8 +- .../rustjava/net/test_file_url_connection.rs | 8 +- .../rustjava/net/test_jar_url_connection.rs | 72 +- jvm/src/class_loader.rs | 27 +- jvm/src/jvm.rs | 163 +- jvm/src/runtime/java_io_input_stream.rs | 4 +- jvm/src/runtime/java_lang_class_loader.rs | 16 +- jvm/tests/test_garbage_collection.rs | 24 +- jvm/tests/test_string.rs | 16 +- jvm_rust/src/interpreter.rs | 6 +- src/lib.rs | 20 +- test_data/VirtualDispatchSemantics.class | Bin 0 -> 931 bytes test_data/VirtualDispatchSemantics.txt | 5 + test_data/dispatch/base/PackageBase.class | Bin 0 -> 352 bytes test_data/dispatch/base/ProtectedBridge.class | Bin 0 -> 321 bytes test_data/dispatch/base/PublicBridge.class | Bin 0 -> 312 bytes .../dispatch/base/SamePackageChild.class | Bin 0 -> 319 bytes test_data/dispatch/foreign/ForeignChild.class | Bin 0 -> 319 bytes .../foreign/ForeignProtectedGrandchild.class | Bin 0 -> 354 bytes .../foreign/ForeignPublicGrandchild.class | Bin 0 -> 342 bytes .../interfaces/InheritedOperation.class | Bin 0 -> 180 bytes .../interfaces/InterfaceImplementation.class | Bin 0 -> 359 bytes .../dispatch/interfaces/InterfaceOwner.class | Bin 0 -> 268 bytes test_data/src/VirtualDispatchSemantics.java | 25 + test_data/src/dispatch/base/PackageBase.java | 11 + .../src/dispatch/base/ProtectedBridge.java | 8 + test_data/src/dispatch/base/PublicBridge.java | 8 + .../src/dispatch/base/SamePackageChild.java | 8 + .../src/dispatch/foreign/ForeignChild.java | 9 + .../foreign/ForeignProtectedGrandchild.java | 10 + .../foreign/ForeignPublicGrandchild.java | 10 + .../interfaces/InheritedOperation.java | 5 + .../interfaces/InterfaceImplementation.java | 8 + .../dispatch/interfaces/InterfaceOwner.java | 3 + 243 files changed, 18812 insertions(+), 4835 deletions(-) create mode 100644 test_data/VirtualDispatchSemantics.class create mode 100644 test_data/VirtualDispatchSemantics.txt create mode 100644 test_data/dispatch/base/PackageBase.class create mode 100644 test_data/dispatch/base/ProtectedBridge.class create mode 100644 test_data/dispatch/base/PublicBridge.class create mode 100644 test_data/dispatch/base/SamePackageChild.class create mode 100644 test_data/dispatch/foreign/ForeignChild.class create mode 100644 test_data/dispatch/foreign/ForeignProtectedGrandchild.class create mode 100644 test_data/dispatch/foreign/ForeignPublicGrandchild.class create mode 100644 test_data/dispatch/interfaces/InheritedOperation.class create mode 100644 test_data/dispatch/interfaces/InterfaceImplementation.class create mode 100644 test_data/dispatch/interfaces/InterfaceOwner.class create mode 100644 test_data/src/VirtualDispatchSemantics.java create mode 100644 test_data/src/dispatch/base/PackageBase.java create mode 100644 test_data/src/dispatch/base/ProtectedBridge.java create mode 100644 test_data/src/dispatch/base/PublicBridge.java create mode 100644 test_data/src/dispatch/base/SamePackageChild.java create mode 100644 test_data/src/dispatch/foreign/ForeignChild.java create mode 100644 test_data/src/dispatch/foreign/ForeignProtectedGrandchild.java create mode 100644 test_data/src/dispatch/foreign/ForeignPublicGrandchild.java create mode 100644 test_data/src/dispatch/interfaces/InheritedOperation.java create mode 100644 test_data/src/dispatch/interfaces/InterfaceImplementation.java create mode 100644 test_data/src/dispatch/interfaces/InterfaceOwner.java diff --git a/java_runtime/src/classes/java/io/buffered_input_stream.rs b/java_runtime/src/classes/java/io/buffered_input_stream.rs index 09fcf1bd..f600afad 100644 --- a/java_runtime/src/classes/java/io/buffered_input_stream.rs +++ b/java_runtime/src/classes/java/io/buffered_input_stream.rs @@ -142,7 +142,13 @@ impl BufferedInputStream { jvm.put_field(this, "count", "I", position).await?; let read: i32 = jvm - .invoke_virtual(&r#in, "read", "([BII)I", (buffer, position, buffer_length - position)) + .invoke_virtual( + &r#in, + "java/io/InputStream", + "read", + "([BII)I", + (buffer, position, buffer_length - position), + ) .await?; if read > 0 { jvm.put_field(this, "count", "I", position + read).await?; @@ -233,7 +239,7 @@ impl BufferedInputStream { total += copied; if total < length { - let available: i32 = jvm.invoke_virtual(&r#in, "available", "()I", ()).await?; + let available: i32 = jvm.invoke_virtual(&r#in, "java/io/InputStream", "available", "()I", ()).await?; if available == 0 { break; } @@ -260,7 +266,7 @@ impl BufferedInputStream { if position >= count { let mark_position: i32 = jvm.get_field(&this, "markpos", "I").await?; if mark_position < 0 { - return jvm.invoke_virtual(&r#in, "skip", "(J)J", (amount,)).await; + return jvm.invoke_virtual(&r#in, "java/io/InputStream", "skip", "(J)J", (amount,)).await; } if Self::fill(jvm, &mut this).await? == -1 { return Ok(0); @@ -284,7 +290,7 @@ impl BufferedInputStream { } let position: i32 = jvm.get_field(&this, "pos", "I").await?; let count: i32 = jvm.get_field(&this, "count", "I").await?; - let underlying: i32 = jvm.invoke_virtual(&r#in, "available", "()I", ()).await?; + let underlying: i32 = jvm.invoke_virtual(&r#in, "java/io/InputStream", "available", "()I", ()).await?; Ok((count - position).saturating_add(underlying)) } @@ -327,6 +333,6 @@ impl BufferedInputStream { let null_buffer: ClassInstanceRef> = None.into(); jvm.put_field(&mut this, "in", "Ljava/io/InputStream;", null_input).await?; jvm.put_field(&mut this, "buf", "[B", null_buffer).await?; - jvm.invoke_virtual(&r#in, "close", "()V", ()).await + jvm.invoke_virtual(&r#in, "java/io/InputStream", "close", "()V", ()).await } } diff --git a/java_runtime/src/classes/java/io/buffered_output_stream.rs b/java_runtime/src/classes/java/io/buffered_output_stream.rs index 1e9b24ac..03526b95 100644 --- a/java_runtime/src/classes/java/io/buffered_output_stream.rs +++ b/java_runtime/src/classes/java/io/buffered_output_stream.rs @@ -81,7 +81,9 @@ impl BufferedOutputStream { } let count: i32 = jvm.get_field(this, "count", "I").await?; if count > 0 { - let _: () = jvm.invoke_virtual(&out, "write", "([BII)V", (buffer, 0, count)).await?; + let _: () = jvm + .invoke_virtual(&out, "java/io/OutputStream", "write", "([BII)V", (buffer, 0, count)) + .await?; jvm.put_field(this, "count", "I", 0).await?; } Ok(()) @@ -131,7 +133,9 @@ impl BufferedOutputStream { let buffer_length = jvm.array_length(&buffer).await? as i32; if length >= buffer_length { Self::flush_buffer(jvm, &mut this).await?; - return jvm.invoke_virtual(&out, "write", "([BII)V", (bytes, offset, length)).await; + return jvm + .invoke_virtual(&out, "java/io/OutputStream", "write", "([BII)V", (bytes, offset, length)) + .await; } let mut count: i32 = jvm.get_field(&this, "count", "I").await?; @@ -156,6 +160,6 @@ impl BufferedOutputStream { Self::flush_buffer(jvm, &mut this).await?; let out: ClassInstanceRef = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - jvm.invoke_virtual(&out, "flush", "()V", ()).await + jvm.invoke_virtual(&out, "java/io/OutputStream", "flush", "()V", ()).await } } diff --git a/java_runtime/src/classes/java/io/buffered_reader.rs b/java_runtime/src/classes/java/io/buffered_reader.rs index 5b1770e3..757fe1ad 100644 --- a/java_runtime/src/classes/java/io/buffered_reader.rs +++ b/java_runtime/src/classes/java/io/buffered_reader.rs @@ -172,7 +172,13 @@ impl BufferedReader { let mut read; loop { read = jvm - .invoke_virtual(&r#in, "read", "([CII)I", (cb.clone(), destination, capacity - destination)) + .invoke_virtual( + &r#in, + "java/io/Reader", + "read", + "([CII)I", + (cb.clone(), destination, capacity - destination), + ) .await?; if read != 0 { break; @@ -271,7 +277,7 @@ impl BufferedReader { let mut next_char: i32 = jvm.get_field(&this, "nextChar", "I").await?; let mut n_chars: i32 = jvm.get_field(&this, "nChars", "I").await?; if next_char >= n_chars { - if total > 0 && !jvm.invoke_virtual::<_, bool>(&r#in, "ready", "()Z", ()).await? { + if total > 0 && !jvm.invoke_virtual::<_, bool>(&r#in, "java/io/Reader", "ready", "()Z", ()).await? { break; } if Self::fill(jvm, &mut this).await? <= 0 { @@ -435,7 +441,7 @@ impl BufferedReader { let mut next_char: i32 = jvm.get_field(&this, "nextChar", "I").await?; let mut n_chars: i32 = jvm.get_field(&this, "nChars", "I").await?; if jvm.get_field::(&this, "skipLF", "Z").await? { - if next_char >= n_chars && jvm.invoke_virtual::<_, bool>(&r#in, "ready", "()Z", ()).await? { + if next_char >= n_chars && jvm.invoke_virtual::<_, bool>(&r#in, "java/io/Reader", "ready", "()Z", ()).await? { let _ = Self::fill(jvm, &mut this).await?; next_char = jvm.get_field(&this, "nextChar", "I").await?; n_chars = jvm.get_field(&this, "nChars", "I").await?; @@ -454,7 +460,7 @@ impl BufferedReader { if next_char < n_chars { return Ok(true); } - jvm.invoke_virtual(&r#in, "ready", "()Z", ()).await + jvm.invoke_virtual(&r#in, "java/io/Reader", "ready", "()Z", ()).await } async fn mark_supported(_: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -528,7 +534,7 @@ impl BufferedReader { return Ok(()); } - let result = jvm.invoke_virtual(&r#in, "close", "()V", ()).await; + let result = jvm.invoke_virtual(&r#in, "java/io/Reader", "close", "()V", ()).await; let closed: ClassInstanceRef = None.into(); jvm.put_field(&mut this, "in", "Ljava/io/Reader;", closed).await?; let released: ClassInstanceRef> = None.into(); diff --git a/java_runtime/src/classes/java/io/buffered_writer.rs b/java_runtime/src/classes/java/io/buffered_writer.rs index 9f4a63b5..39ea303f 100644 --- a/java_runtime/src/classes/java/io/buffered_writer.rs +++ b/java_runtime/src/classes/java/io/buffered_writer.rs @@ -120,7 +120,9 @@ impl BufferedWriter { } let next_char: i32 = jvm.get_field(this, "nextChar", "I").await?; if next_char > 0 { - let _: () = jvm.invoke_virtual(&out, "write", "([CII)V", (buffer, 0, next_char)).await?; + let _: () = jvm + .invoke_virtual(&out, "java/io/Writer", "write", "([CII)V", (buffer, 0, next_char)) + .await?; jvm.put_field(this, "nextChar", "I", 0).await?; } Ok(()) @@ -189,7 +191,9 @@ impl BufferedWriter { let n_chars: i32 = jvm.get_field(&this, "nChars", "I").await?; if length >= n_chars { Self::flush_buffer(jvm, &mut this).await?; - return jvm.invoke_virtual(&out, "write", "([CII)V", (chars, offset, length)).await; + return jvm + .invoke_virtual(&out, "java/io/Writer", "write", "([CII)V", (chars, offset, length)) + .await; } let mut source_position = offset; @@ -245,7 +249,7 @@ impl BufferedWriter { if value.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "string is null").await); } - let string_length: i32 = jvm.invoke_virtual(&value, "length", "()I", ()).await?; + let string_length: i32 = jvm.invoke_virtual(&value, "java/lang/String", "length", "()I", ()).await?; if offset < 0 || length < 0 || offset > string_length - length { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "Invalid offset or length").await); } @@ -259,6 +263,7 @@ impl BufferedWriter { let _: () = jvm .invoke_virtual( &value, + "java/lang/String", "getChars", "(II[CI)V", (source_position, source_position + copied, buffer, next_char), @@ -283,7 +288,7 @@ impl BufferedWriter { tracing::debug!("java.io.BufferedWriter::newLine({this:?})"); let line_separator: ClassInstanceRef = jvm.get_field(&this, "lineSeparator", "Ljava/lang/String;").await?; - let length: i32 = jvm.invoke_virtual(&line_separator, "length", "()I", ()).await?; + let length: i32 = jvm.invoke_virtual(&line_separator, "java/lang/String", "length", "()I", ()).await?; Self::write_string_locked(jvm, this, line_separator, 0, length).await } @@ -297,7 +302,7 @@ impl BufferedWriter { Self::flush_buffer(jvm, &mut this).await?; let out: ClassInstanceRef = jvm.get_field(&this, "out", "Ljava/io/Writer;").await?; - jvm.invoke_virtual(&out, "flush", "()V", ()).await + jvm.invoke_virtual(&out, "java/io/Writer", "flush", "()V", ()).await } async fn close(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { @@ -313,7 +318,7 @@ impl BufferedWriter { return Ok(()); } let flush_result = Self::flush_buffer(jvm, &mut this).await; - let close_result: Result<()> = jvm.invoke_virtual(&out, "close", "()V", ()).await; + let close_result: Result<()> = jvm.invoke_virtual(&out, "java/io/Writer", "close", "()V", ()).await; let null_writer: ClassInstanceRef = None.into(); let null_buffer: ClassInstanceRef> = None.into(); let clear_out_result = jvm.put_field(&mut this, "out", "Ljava/io/Writer;", null_writer).await; diff --git a/java_runtime/src/classes/java/io/byte_array_output_stream.rs b/java_runtime/src/classes/java/io/byte_array_output_stream.rs index 9a659a33..9a8c690d 100644 --- a/java_runtime/src/classes/java/io/byte_array_output_stream.rs +++ b/java_runtime/src/classes/java/io/byte_array_output_stream.rs @@ -140,7 +140,8 @@ impl ByteArrayOutputStream { let buf: ClassInstanceRef> = jvm.get_field(&this, "buf", "[B").await?; let count: i32 = jvm.get_field(&this, "count", "I").await?; - jvm.invoke_virtual(&out, "write", "([BII)V", (buf, 0, count)).await + jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "([BII)V", (buf, 0, count)) + .await } async fn to_byte_array(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result>> { diff --git a/java_runtime/src/classes/java/io/char_array_writer.rs b/java_runtime/src/classes/java/io/char_array_writer.rs index 92a12c58..f591394e 100644 --- a/java_runtime/src/classes/java/io/char_array_writer.rs +++ b/java_runtime/src/classes/java/io/char_array_writer.rs @@ -185,7 +185,7 @@ impl CharArrayWriter { if value.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "string is null").await); } - let source_length: i32 = jvm.invoke_virtual(&value, "length", "()I", ()).await?; + let source_length: i32 = jvm.invoke_virtual(&value, "java/lang/String", "length", "()I", ()).await?; if offset < 0 || length < 0 || offset > source_length - length { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "Invalid offset or length").await); } @@ -193,7 +193,13 @@ impl CharArrayWriter { Self::ensure_capacity(jvm, &mut this, count + length).await?; let buffer: ClassInstanceRef> = jvm.get_field(&this, "buf", "[C").await?; let _: () = jvm - .invoke_virtual(&value, "getChars", "(II[CI)V", (offset, offset + length, buffer, count)) + .invoke_virtual( + &value, + "java/lang/String", + "getChars", + "(II[CI)V", + (offset, offset + length, buffer, count), + ) .await?; jvm.put_field(&mut this, "count", "I", count + length).await } @@ -211,7 +217,7 @@ impl CharArrayWriter { } let buffer: ClassInstanceRef> = jvm.get_field(&this, "buf", "[C").await?; let count: i32 = jvm.get_field(&this, "count", "I").await?; - jvm.invoke_virtual(&out, "write", "([CII)V", (buffer, 0, count)).await + jvm.invoke_virtual(&out, "java/io/Writer", "write", "([CII)V", (buffer, 0, count)).await } async fn reset(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { diff --git a/java_runtime/src/classes/java/io/data_input_stream.rs b/java_runtime/src/classes/java/io/data_input_stream.rs index 1d2eb426..20cc5c0d 100644 --- a/java_runtime/src/classes/java/io/data_input_stream.rs +++ b/java_runtime/src/classes/java/io/data_input_stream.rs @@ -155,9 +155,13 @@ impl DataInputStream { async fn read_utf(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.io.DataInputStream::readUTF({this:?})"); - let length: i32 = jvm.invoke_virtual(&this, "readUnsignedShort", "()I", ()).await?; + let length: i32 = jvm + .invoke_virtual(&this, "java/io/DataInputStream", "readUnsignedShort", "()I", ()) + .await?; let java_array = jvm.instantiate_array("B", length as usize).await?; - let _: () = jvm.invoke_virtual(&this, "readFully", "([BII)V", (java_array.clone(), 0, length)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/DataInputStream", "readFully", "([BII)V", (java_array.clone(), 0, length)) + .await?; let bytes: Vec = jvm.load_array(&java_array, 0, length as usize).await?; let bytes: Vec = bytes.into_iter().map(|value| value as u8).collect(); @@ -197,7 +201,8 @@ impl DataInputStream { async fn read_utf_from_input(jvm: &Jvm, _: &mut RuntimeContext, input: ClassInstanceRef) -> Result> { tracing::debug!("java.io.DataInputStream::readUTF({input:?})"); - jvm.invoke_virtual(&input, "readUTF", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&input, &input.class_definition().name(), "readUTF", "()Ljava/lang/String;", ()) + .await } async fn read_fully(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, b: ClassInstanceRef>) -> Result<()> { @@ -205,7 +210,9 @@ impl DataInputStream { let length = jvm.array_length(&b).await?; - let _: () = jvm.invoke_virtual(&this, "readFully", "([BII)V", (b.clone(), 0, length as i32)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/DataInputStream", "readFully", "([BII)V", (b.clone(), 0, length as i32)) + .await?; Ok(()) } @@ -222,7 +229,9 @@ impl DataInputStream { let mut read = 0; while read < len { - let r: i32 = jvm.invoke_virtual(&this, "read", "([BII)I", (b.clone(), off + read, len - read)).await?; + let r: i32 = jvm + .invoke_virtual(&this, "java/io/DataInputStream", "read", "([BII)I", (b.clone(), off + read, len - read)) + .await?; if r == -1 { return Err(jvm.exception("java/io/EOFException", "End of stream reached before reading fully").await); } @@ -236,14 +245,14 @@ impl DataInputStream { tracing::debug!("java.io.DataInputStream::skipBytes({this:?}, {n:?})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - let skipped: i64 = jvm.invoke_virtual(&r#in, "skip", "(J)J", (n as i64,)).await?; + let skipped: i64 = jvm.invoke_virtual(&r#in, "java/io/InputStream", "skip", "(J)J", (n as i64,)).await?; Ok(skipped as _) } async fn read_required_byte(jvm: &Jvm, this: &ClassInstanceRef) -> Result { let r#in = jvm.get_field(this, "in", "Ljava/io/InputStream;").await?; - let value: i32 = jvm.invoke_virtual(&r#in, "read", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&r#in, "java/io/InputStream", "read", "()I", ()).await?; if value == -1 { return Err(jvm.exception("java/io/EOFException", "End of stream").await); } diff --git a/java_runtime/src/classes/java/io/data_output_stream.rs b/java_runtime/src/classes/java/io/data_output_stream.rs index 1fc9399c..7bf2a652 100644 --- a/java_runtime/src/classes/java/io/data_output_stream.rs +++ b/java_runtime/src/classes/java/io/data_output_stream.rs @@ -55,7 +55,7 @@ impl DataOutputStream { tracing::debug!("java.io.DataOutputStream::write({this:?}, {b:?})"); let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - let _: () = jvm.invoke_virtual(&out, "write", "(I)V", (b,)).await?; + let _: () = jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "(I)V", (b,)).await?; Ok(()) } @@ -64,7 +64,7 @@ impl DataOutputStream { tracing::debug!("java.io.DataOutputStream::writeByte({this:?}, {v:?})"); let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - let _: () = jvm.invoke_virtual(&out, "write", "(I)V", (v,)).await?; + let _: () = jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "(I)V", (v,)).await?; Ok(()) } @@ -72,7 +72,9 @@ impl DataOutputStream { async fn write_boolean(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, v: bool) -> Result<()> { tracing::debug!("java.io.DataOutputStream::writeBoolean({this:?}, {v:?})"); - let _: () = jvm.invoke_virtual(&this, "writeByte", "(I)V", (v as i32,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/DataOutputStream", "writeByte", "(I)V", (v as i32,)) + .await?; Ok(()) } @@ -85,14 +87,15 @@ impl DataOutputStream { jvm.store_array(&mut byte_array, 0, cast_vec::(bytes.to_vec())).await?; let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - let _: () = jvm.invoke_virtual(&out, "write", "([B)V", (byte_array,)).await?; + let _: () = jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "([B)V", (byte_array,)).await?; Ok(()) } async fn write_char(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: i32) -> Result<()> { tracing::debug!("java.io.DataOutputStream::writeChar({this:?}, {value:?})"); - jvm.invoke_virtual(&this, "writeShort", "(I)V", (value & 0xffff,)).await + jvm.invoke_virtual(&this, "java/io/DataOutputStream", "writeShort", "(I)V", (value & 0xffff,)) + .await } async fn write_int(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, i: i32) -> Result<()> { @@ -103,7 +106,7 @@ impl DataOutputStream { jvm.store_array(&mut byte_array, 0, cast_vec::(bytes.to_vec())).await?; let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - let _: () = jvm.invoke_virtual(&out, "write", "([B)V", (byte_array,)).await?; + let _: () = jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "([B)V", (byte_array,)).await?; Ok(()) } @@ -116,38 +119,40 @@ impl DataOutputStream { jvm.store_array(&mut byte_array, 0, cast_vec::(bytes.to_vec())).await?; let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - let _: () = jvm.invoke_virtual(&out, "write", "([B)V", (byte_array,)).await?; + let _: () = jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "([B)V", (byte_array,)).await?; Ok(()) } async fn write_float(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f32) -> Result<()> { tracing::debug!("java.io.DataOutputStream::writeFloat({this:?}, {value:?})"); - jvm.invoke_virtual(&this, "writeInt", "(I)V", (value.to_bits() as i32,)).await + jvm.invoke_virtual(&this, "java/io/DataOutputStream", "writeInt", "(I)V", (value.to_bits() as i32,)) + .await } async fn write_double(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f64) -> Result<()> { tracing::debug!("java.io.DataOutputStream::writeDouble({this:?}, {value:?})"); - jvm.invoke_virtual(&this, "writeLong", "(J)V", (value.to_bits() as i64,)).await + jvm.invoke_virtual(&this, "java/io/DataOutputStream", "writeLong", "(J)V", (value.to_bits() as i64,)) + .await } async fn write_bytes(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, s: ClassInstanceRef) -> Result<()> { tracing::debug!("java.io.DataOutputStream::writeBytes({this:?}, {s:?})"); - let chars: ClassInstanceRef> = jvm.invoke_virtual(&s, "toCharArray", "()[C", ()).await?; + let chars: ClassInstanceRef> = jvm.invoke_virtual(&s, "java/lang/String", "toCharArray", "()[C", ()).await?; let length = jvm.array_length(&chars).await?; let chars: Vec = jvm.load_array(&chars, 0, length).await?; let mut bytes = jvm.instantiate_array("B", chars.len()).await?; jvm.store_array(&mut bytes, 0, chars.into_iter().map(|value| value as i8)).await?; let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - jvm.invoke_virtual(&out, "write", "([B)V", (bytes,)).await + jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "([B)V", (bytes,)).await } async fn write_chars(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, s: ClassInstanceRef) -> Result<()> { tracing::debug!("java.io.DataOutputStream::writeChars({this:?}, {s:?})"); - let chars: ClassInstanceRef> = jvm.invoke_virtual(&s, "toCharArray", "()[C", ()).await?; + let chars: ClassInstanceRef> = jvm.invoke_virtual(&s, "java/lang/String", "toCharArray", "()[C", ()).await?; let length = jvm.array_length(&chars).await?; let chars: Vec = jvm.load_array(&chars, 0, length).await?; let mut data = Vec::with_capacity(chars.len() * 2); @@ -160,13 +165,13 @@ impl DataOutputStream { jvm.store_array(&mut bytes, 0, data).await?; let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - jvm.invoke_virtual(&out, "write", "([B)V", (bytes,)).await + jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "([B)V", (bytes,)).await } async fn write_utf(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, s: ClassInstanceRef) -> Result<()> { tracing::debug!("java.io.DataOutputStream::writeUTF({this:?}, {s:?})"); - let chars: ClassInstanceRef> = jvm.invoke_virtual(&s, "toCharArray", "()[C", ()).await?; + let chars: ClassInstanceRef> = jvm.invoke_virtual(&s, "java/lang/String", "toCharArray", "()[C", ()).await?; let length = jvm.array_length(&chars).await?; let chars: Vec = jvm.load_array(&chars, 0, length).await?; let mut data = Vec::new(); @@ -187,20 +192,22 @@ impl DataOutputStream { return Err(jvm.exception("java/io/UTFDataFormatException", "encoded string is too long").await); } - let _: () = jvm.invoke_virtual(&this, "writeShort", "(I)V", (data.len() as i32,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/DataOutputStream", "writeShort", "(I)V", (data.len() as i32,)) + .await?; let mut bytes = jvm.instantiate_array("B", data.len()).await?; jvm.store_array(&mut bytes, 0, data).await?; let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - jvm.invoke_virtual(&out, "write", "([B)V", (bytes,)).await + jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "([B)V", (bytes,)).await } async fn close(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { tracing::debug!("java.io.DataOutputStream::close({this:?})"); let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - let _: () = jvm.invoke_virtual(&out, "close", "()V", []).await?; + let _: () = jvm.invoke_virtual(&out, "java/io/OutputStream", "close", "()V", []).await?; Ok(()) } @@ -209,7 +216,7 @@ impl DataOutputStream { tracing::debug!("java.io.DataOutputStream::flush({this:?})"); let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - let _: () = jvm.invoke_virtual(&out, "flush", "()V", []).await?; + let _: () = jvm.invoke_virtual(&out, "java/io/OutputStream", "flush", "()V", []).await?; Ok(()) } diff --git a/java_runtime/src/classes/java/io/file.rs b/java_runtime/src/classes/java/io/file.rs index 905fd83e..641f5bf7 100644 --- a/java_runtime/src/classes/java/io/file.rs +++ b/java_runtime/src/classes/java/io/file.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, JavaChar, Jvm, Result, runtime::JavaLangString}; use crate::{FileType, RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -17,13 +17,13 @@ impl File { interfaces: vec!["java/io/Serializable"], methods: vec![ JavaMethodProto::new("", "()V", Self::clinit, MethodAccessFlags::STATIC), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init, Default::default()), - JavaMethodProto::new("getPath", "()Ljava/lang/String;", Self::get_path, Default::default()), - JavaMethodProto::new("exists", "()Z", Self::exists, Default::default()), - JavaMethodProto::new("isDirectory", "()Z", Self::is_directory, Default::default()), - JavaMethodProto::new("isFile", "()Z", Self::is_file, Default::default()), - JavaMethodProto::new("delete", "()Z", Self::delete, Default::default()), - JavaMethodProto::new("length", "()J", Self::length, Default::default()), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getPath", "()Ljava/lang/String;", Self::get_path, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("exists", "()Z", Self::exists, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("isDirectory", "()Z", Self::is_directory, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("isFile", "()Z", Self::is_file, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("delete", "()Z", Self::delete, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("length", "()J", Self::length, MethodAccessFlags::PUBLIC), ], fields: vec![ JavaFieldProto::new( @@ -48,7 +48,7 @@ impl File { ), JavaFieldProto::new("path", "Ljava/lang/String;", Default::default()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -101,7 +101,7 @@ impl File { async fn exists(jvm: &Jvm, context: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.io.File::exists({this:?})"); - let path = jvm.invoke_virtual(&this, "getPath", "()Ljava/lang/String;", ()).await?; + let path = jvm.invoke_virtual(&this, "java/io/File", "getPath", "()Ljava/lang/String;", ()).await?; let path = JavaLangString::to_rust_string(jvm, &path).await?; Ok(context.metadata(&path).await.is_ok()) @@ -110,7 +110,7 @@ impl File { async fn is_directory(jvm: &Jvm, context: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.io.File::isDirectory({this:?})"); - let path = jvm.invoke_virtual(&this, "getPath", "()Ljava/lang/String;", ()).await?; + let path = jvm.invoke_virtual(&this, "java/io/File", "getPath", "()Ljava/lang/String;", ()).await?; let path = JavaLangString::to_rust_string(jvm, &path).await?; Ok(context.metadata(&path).await.is_ok_and(|x| x.r#type == FileType::Directory)) @@ -119,7 +119,7 @@ impl File { async fn is_file(jvm: &Jvm, context: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.io.File::isFile({this:?})"); - let path = jvm.invoke_virtual(&this, "getPath", "()Ljava/lang/String;", ()).await?; + let path = jvm.invoke_virtual(&this, "java/io/File", "getPath", "()Ljava/lang/String;", ()).await?; let path = JavaLangString::to_rust_string(jvm, &path).await?; Ok(context.metadata(&path).await.is_ok_and(|x| x.r#type == FileType::File)) @@ -128,7 +128,7 @@ impl File { async fn delete(jvm: &Jvm, context: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.io.File::delete({this:?})"); - let path = jvm.invoke_virtual(&this, "getPath", "()Ljava/lang/String;", ()).await?; + let path = jvm.invoke_virtual(&this, "java/io/File", "getPath", "()Ljava/lang/String;", ()).await?; let path = JavaLangString::to_rust_string(jvm, &path).await?; Ok(context.unlink(&path).await.is_ok()) @@ -137,7 +137,7 @@ impl File { async fn length(jvm: &Jvm, context: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.io.File::length({this:?})"); - let path = jvm.invoke_virtual(&this, "getPath", "()Ljava/lang/String;", ()).await?; + let path = jvm.invoke_virtual(&this, "java/io/File", "getPath", "()Ljava/lang/String;", ()).await?; let path = JavaLangString::to_rust_string(jvm, &path).await?; // File.length() is 0 when the file does not exist diff --git a/java_runtime/src/classes/java/io/file_input_stream.rs b/java_runtime/src/classes/java/io/file_input_stream.rs index 627e1fd1..b75e3ea9 100644 --- a/java_runtime/src/classes/java/io/file_input_stream.rs +++ b/java_runtime/src/classes/java/io/file_input_stream.rs @@ -40,7 +40,7 @@ impl FileInputStream { async fn init(jvm: &Jvm, context: &mut RuntimeContext, this: ClassInstanceRef, file: ClassInstanceRef) -> Result<()> { tracing::debug!("java.io.FileInputStream::({this:?}, {file:?})"); - let path = jvm.invoke_virtual(&file, "getPath", "()Ljava/lang/String;", ()).await?; + let path = jvm.invoke_virtual(&file, "java/io/File", "getPath", "()Ljava/lang/String;", ()).await?; let path = JavaLangString::to_rust_string(jvm, &path).await?; let fd = context diff --git a/java_runtime/src/classes/java/io/file_output_stream.rs b/java_runtime/src/classes/java/io/file_output_stream.rs index 255c355a..61bf7dc0 100644 --- a/java_runtime/src/classes/java/io/file_output_stream.rs +++ b/java_runtime/src/classes/java/io/file_output_stream.rs @@ -56,7 +56,7 @@ impl FileOutputStream { ) -> Result<()> { tracing::debug!("java.io.FileOutputStream::({this:?}, {file:?}, {append})"); - let path = jvm.invoke_virtual(&file, "getPath", "()Ljava/lang/String;", ()).await?; + let path = jvm.invoke_virtual(&file, "java/io/File", "getPath", "()Ljava/lang/String;", ()).await?; let path = JavaLangString::to_rust_string(jvm, &path).await?; let fd = context diff --git a/java_runtime/src/classes/java/io/filter_input_stream.rs b/java_runtime/src/classes/java/io/filter_input_stream.rs index e4df431f..7a271523 100644 --- a/java_runtime/src/classes/java/io/filter_input_stream.rs +++ b/java_runtime/src/classes/java/io/filter_input_stream.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::FieldAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::io::InputStream}; @@ -16,19 +16,19 @@ impl FilterInputStream { parent_class: Some("java/io/InputStream"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/InputStream;)V", Self::init, Default::default()), - JavaMethodProto::new("available", "()I", Self::available, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), - JavaMethodProto::new("read", "()I", Self::read_byte_int, Default::default()), - JavaMethodProto::new("read", "([B)I", Self::read, Default::default()), - JavaMethodProto::new("read", "([BII)I", Self::read_with_offset_length, Default::default()), - JavaMethodProto::new("skip", "(J)J", Self::skip, Default::default()), - JavaMethodProto::new("mark", "(I)V", Self::mark, Default::default()), - JavaMethodProto::new("reset", "()V", Self::reset, Default::default()), - JavaMethodProto::new("markSupported", "()Z", Self::mark_supported, Default::default()), + JavaMethodProto::new("", "(Ljava/io/InputStream;)V", Self::init, MethodAccessFlags::PROTECTED), + JavaMethodProto::new("available", "()I", Self::available, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "()I", Self::read_byte_int, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "([B)I", Self::read, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "([BII)I", Self::read_with_offset_length, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("skip", "(J)J", Self::skip, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("mark", "(I)V", Self::mark, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("reset", "()V", Self::reset, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("markSupported", "()Z", Self::mark_supported, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("in", "Ljava/io/InputStream;", FieldAccessFlags::PROTECTED)], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -46,7 +46,7 @@ impl FilterInputStream { tracing::debug!("java.io.FilterInputStream::available({this:?})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - let available: i32 = jvm.invoke_virtual(&r#in, "available", "()I", ()).await?; + let available: i32 = jvm.invoke_virtual(&r#in, "java/io/InputStream", "available", "()I", ()).await?; Ok(available) } @@ -55,7 +55,7 @@ impl FilterInputStream { tracing::debug!("java.io.FilterInputStream::close({this:?})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - let _: () = jvm.invoke_virtual(&r#in, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&r#in, "java/io/InputStream", "close", "()V", ()).await?; Ok(()) } @@ -64,7 +64,7 @@ impl FilterInputStream { tracing::debug!("java.io.FilterInputStream::reset({this:?})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - let _: () = jvm.invoke_virtual(&r#in, "reset", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&r#in, "java/io/InputStream", "reset", "()V", ()).await?; Ok(()) } @@ -72,26 +72,26 @@ impl FilterInputStream { async fn skip(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, n: i64) -> Result { tracing::debug!("java.io.FilterInputStream::skip({this:?}, {n})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - jvm.invoke_virtual(&r#in, "skip", "(J)J", (n,)).await + jvm.invoke_virtual(&r#in, "java/io/InputStream", "skip", "(J)J", (n,)).await } async fn mark(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, readlimit: i32) -> Result<()> { tracing::debug!("java.io.FilterInputStream::mark({this:?}, {readlimit})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - jvm.invoke_virtual(&r#in, "mark", "(I)V", (readlimit,)).await + jvm.invoke_virtual(&r#in, "java/io/InputStream", "mark", "(I)V", (readlimit,)).await } async fn mark_supported(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.io.FilterInputStream::markSupported({this:?})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - jvm.invoke_virtual(&r#in, "markSupported", "()Z", ()).await + jvm.invoke_virtual(&r#in, "java/io/InputStream", "markSupported", "()Z", ()).await } async fn read(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, b: ClassInstanceRef>) -> Result { tracing::debug!("java.io.FilterInputStream::read({this:?}, {b:?})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - let result: i32 = jvm.invoke_virtual(&r#in, "read", "([B)I", (b,)).await?; + let result: i32 = jvm.invoke_virtual(&r#in, "java/io/InputStream", "read", "([B)I", (b,)).await?; Ok(result) } @@ -107,7 +107,7 @@ impl FilterInputStream { tracing::debug!("java.io.FilterInputStream::read({this:?}, {b:?}, {off}, {len})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - let result: i32 = jvm.invoke_virtual(&r#in, "read", "([BII)I", (b, off, len)).await?; + let result: i32 = jvm.invoke_virtual(&r#in, "java/io/InputStream", "read", "([BII)I", (b, off, len)).await?; Ok(result) } @@ -116,7 +116,7 @@ impl FilterInputStream { tracing::debug!("java.io.FilterInputStream::read({this:?})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - let result: i32 = jvm.invoke_virtual(&r#in, "read", "()I", ()).await?; + let result: i32 = jvm.invoke_virtual(&r#in, "java/io/InputStream", "read", "()I", ()).await?; Ok(result) } diff --git a/java_runtime/src/classes/java/io/filter_output_stream.rs b/java_runtime/src/classes/java/io/filter_output_stream.rs index 00b5c2c9..e8aaf95d 100644 --- a/java_runtime/src/classes/java/io/filter_output_stream.rs +++ b/java_runtime/src/classes/java/io/filter_output_stream.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaError, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::io::OutputStream}; @@ -16,14 +16,14 @@ impl FilterOutputStream { parent_class: Some("java/io/OutputStream"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/OutputStream;)V", Self::init, Default::default()), - JavaMethodProto::new("write", "([BII)V", Self::write_bytes_offset, Default::default()), - JavaMethodProto::new("write", "(I)V", Self::write, Default::default()), - JavaMethodProto::new("flush", "()V", Self::flush, Default::default()), + JavaMethodProto::new("", "(Ljava/io/OutputStream;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("write", "([BII)V", Self::write_bytes_offset, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("write", "(I)V", Self::write, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("flush", "()V", Self::flush, MethodAccessFlags::PUBLIC), JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("out", "Ljava/io/OutputStream;", FieldAccessFlags::PROTECTED)], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -48,7 +48,9 @@ impl FilterOutputStream { tracing::debug!(" java.io.FilterOutputStream::write({this:?}, {bytes:?}, {offset:?}, {length:?})"); let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - let _: () = jvm.invoke_virtual(&out, "write", "([BII)V", (bytes, offset, length)).await?; + let _: () = jvm + .invoke_virtual(&out, "java/io/OutputStream", "write", "([BII)V", (bytes, offset, length)) + .await?; Ok(()) } @@ -57,7 +59,7 @@ impl FilterOutputStream { tracing::debug!("java.io.FilterOutputStream::write({this:?}, {byte:?})"); let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - let _: () = jvm.invoke_virtual(&out, "write", "(I)V", (byte,)).await?; + let _: () = jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "(I)V", (byte,)).await?; Ok(()) } @@ -65,7 +67,7 @@ impl FilterOutputStream { async fn flush(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { tracing::debug!("java.io.FilterOutputStream::flush({this:?})"); let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - jvm.invoke_virtual(&out, "flush", "()V", ()).await + jvm.invoke_virtual(&out, "java/io/OutputStream", "flush", "()V", ()).await } async fn close(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result<()> { @@ -76,7 +78,7 @@ impl FilterOutputStream { return Ok(()); } - match jvm.invoke_virtual::<_, ()>(&this, "flush", "()V", ()).await { + match jvm.invoke_virtual::<_, ()>(&this, "java/io/FilterOutputStream", "flush", "()V", ()).await { Ok(()) => {} Err(JavaError::JavaException(exception)) if jvm.is_instance(&*exception, "java/io/IOException") => {} Err(error) => { @@ -86,7 +88,7 @@ impl FilterOutputStream { } } - let close_result: Result<()> = jvm.invoke_virtual(&out, "close", "()V", ()).await; + let close_result: Result<()> = jvm.invoke_virtual(&out, "java/io/OutputStream", "close", "()V", ()).await; let null_output: ClassInstanceRef = None.into(); jvm.put_field(&mut this, "out", "Ljava/io/OutputStream;", null_output).await?; close_result diff --git a/java_runtime/src/classes/java/io/input_stream.rs b/java_runtime/src/classes/java/io/input_stream.rs index b1dc7475..ec9bffd2 100644 --- a/java_runtime/src/classes/java/io/input_stream.rs +++ b/java_runtime/src/classes/java/io/input_stream.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext}; @@ -16,16 +16,16 @@ impl InputStream { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("available", "()I", Self::available, Default::default()), - JavaMethodProto::new("read", "([BII)I", Self::read_offset, Default::default()), - JavaMethodProto::new("read", "([B)I", Self::read, Default::default()), - JavaMethodProto::new_abstract("read", "()I", Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), - JavaMethodProto::new("skip", "(J)J", Self::skip, Default::default()), - JavaMethodProto::new("mark", "(I)V", Self::mark, Default::default()), - JavaMethodProto::new("reset", "()V", Self::reset, Default::default()), - JavaMethodProto::new("markSupported", "()Z", Self::mark_supported, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("available", "()I", Self::available, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "([BII)I", Self::read_offset, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "([B)I", Self::read, MethodAccessFlags::PUBLIC), + JavaMethodProto::new_abstract("read", "()I", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("skip", "(J)J", Self::skip, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("mark", "(I)V", Self::mark, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("reset", "()V", Self::reset, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("markSupported", "()Z", Self::mark_supported, MethodAccessFlags::PUBLIC), ], fields: vec![], access_flags: ClassAccessFlags::ABSTRACT, @@ -48,7 +48,8 @@ impl InputStream { } let array_length = jvm.array_length(&b).await? as i32; - jvm.invoke_virtual(&this, "read", "([BII)I", (b, 0, array_length)).await + jvm.invoke_virtual(&this, "java/io/InputStream", "read", "([BII)I", (b, 0, array_length)) + .await } async fn read_offset( @@ -72,7 +73,7 @@ impl InputStream { return Ok(0); } - let first: i32 = jvm.invoke_virtual(&this, "read", "()I", ()).await?; + let first: i32 = jvm.invoke_virtual(&this, "java/io/InputStream", "read", "()I", ()).await?; if first == -1 { return Ok(-1); } @@ -80,7 +81,7 @@ impl InputStream { let mut count = 1; while count < len { - let value: i32 = jvm.invoke_virtual(&this, "read", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&this, "java/io/InputStream", "read", "()I", ()).await?; if value == -1 { break; } @@ -114,7 +115,9 @@ impl InputStream { let mut remaining = n; while remaining > 0 { let len_to_read = remaining.min(scratch_size) as i32; - let read: i32 = jvm.invoke_virtual(&this, "read", "([BII)I", (scratch.clone(), 0, len_to_read)).await?; + let read: i32 = jvm + .invoke_virtual(&this, "java/io/InputStream", "read", "([BII)I", (scratch.clone(), 0, len_to_read)) + .await?; if read <= 0 { break; } diff --git a/java_runtime/src/classes/java/io/input_stream_reader.rs b/java_runtime/src/classes/java/io/input_stream_reader.rs index 4cf7bb39..d1645fd3 100644 --- a/java_runtime/src/classes/java/io/input_stream_reader.rs +++ b/java_runtime/src/classes/java/io/input_stream_reader.rs @@ -132,7 +132,9 @@ impl InputStreamReader { let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; let temp = jvm.instantiate_array("B", bytes_to_read as _).await?; - let read: i32 = jvm.invoke_virtual(&r#in, "read", "([BII)I", (temp.clone(), 0, bytes_to_read)).await?; + let read: i32 = jvm + .invoke_virtual(&r#in, "java/io/InputStream", "read", "([BII)I", (temp.clone(), 0, bytes_to_read)) + .await?; if read != -1 { let _: () = jvm .invoke_static( @@ -248,7 +250,7 @@ impl InputStreamReader { tracing::debug!("java.io.InputStreamReader::close({this:?})"); let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - let _: () = jvm.invoke_virtual(&r#in, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&r#in, "java/io/InputStream", "close", "()V", ()).await?; Ok(()) } @@ -262,7 +264,7 @@ impl InputStreamReader { } let r#in = jvm.get_field(&this, "in", "Ljava/io/InputStream;").await?; - let available: i32 = jvm.invoke_virtual(&r#in, "available", "()I", ()).await?; + let available: i32 = jvm.invoke_virtual(&r#in, "java/io/InputStream", "available", "()I", ()).await?; Ok(available > 0) } } diff --git a/java_runtime/src/classes/java/io/output_stream.rs b/java_runtime/src/classes/java/io/output_stream.rs index 18e51f95..3cb53fbe 100644 --- a/java_runtime/src/classes/java/io/output_stream.rs +++ b/java_runtime/src/classes/java/io/output_stream.rs @@ -44,7 +44,9 @@ impl OutputStream { } let length = jvm.array_length(&buffer).await?; - let _: () = jvm.invoke_virtual(&this, "write", "([BII)V", (buffer, 0, length as i32)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/OutputStream", "write", "([BII)V", (buffer, 0, length as i32)) + .await?; Ok(()) } @@ -65,7 +67,7 @@ impl OutputStream { let mut bytes = vec![0; length as usize]; jvm.array_raw_buffer(&buffer).await?.read(offset as _, &mut bytes)?; for byte in bytes { - let _: () = jvm.invoke_virtual(&this, "write", "(I)V", (byte as i32,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/OutputStream", "write", "(I)V", (byte as i32,)).await?; } Ok(()) diff --git a/java_runtime/src/classes/java/io/output_stream_writer.rs b/java_runtime/src/classes/java/io/output_stream_writer.rs index ec25827d..b0c857ac 100644 --- a/java_runtime/src/classes/java/io/output_stream_writer.rs +++ b/java_runtime/src/classes/java/io/output_stream_writer.rs @@ -1,6 +1,7 @@ use alloc::{string::String as RustString, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaChar, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -21,16 +22,16 @@ impl OutputStreamWriter { parent_class: Some("java/io/Writer"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/OutputStream;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/io/OutputStream;)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/io/OutputStream;Ljava/lang/String;)V", Self::init_with_encoding, - Default::default(), + MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("write", "([CII)V", Self::write, Default::default()), - JavaMethodProto::new("flush", "()V", Self::flush, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), + JavaMethodProto::new("write", "([CII)V", Self::write, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("flush", "()V", Self::flush, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], fields: vec![ JavaFieldProto::new("out", "Ljava/io/OutputStream;", Default::default()), @@ -38,7 +39,7 @@ impl OutputStreamWriter { JavaFieldProto::new("pendingHighSurrogate", "C", Default::default()), JavaFieldProto::new("hasPendingHighSurrogate", "Z", Default::default()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -139,13 +140,13 @@ impl OutputStreamWriter { jvm.store_array(&mut java_bytes, 0, bytes.into_iter().map(|value| value as i8)).await?; let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - jvm.invoke_virtual(&out, "write", "([B)V", (java_bytes,)).await + jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "([B)V", (java_bytes,)).await } async fn flush(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { tracing::debug!("java.io.OutputStreamWriter::flush({this:?})"); let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - jvm.invoke_virtual(&out, "flush", "()V", ()).await + jvm.invoke_virtual(&out, "java/io/OutputStream", "flush", "()V", ()).await } async fn close(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result<()> { @@ -156,10 +157,12 @@ impl OutputStreamWriter { jvm.put_field(&mut this, "hasPendingHighSurrogate", "Z", false).await?; let mut replacement = jvm.instantiate_array("C", 1).await?; jvm.store_array(&mut replacement, 0, ['?' as JavaChar]).await?; - let _: () = jvm.invoke_virtual(&this, "write", "([CII)V", (replacement, 0, 1)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/OutputStreamWriter", "write", "([CII)V", (replacement, 0, 1)) + .await?; } let out = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; - jvm.invoke_virtual(&out, "close", "()V", ()).await + jvm.invoke_virtual(&out, "java/io/OutputStream", "close", "()V", ()).await } } diff --git a/java_runtime/src/classes/java/io/print_stream.rs b/java_runtime/src/classes/java/io/print_stream.rs index 8aedb9a2..86dbdadb 100644 --- a/java_runtime/src/classes/java/io/print_stream.rs +++ b/java_runtime/src/classes/java/io/print_stream.rs @@ -159,7 +159,13 @@ impl PrintStream { } else { let key = JavaLangString::from_rust_string(jvm, "file.encoding").await?; let encoding: ClassInstanceRef = jvm - .invoke_virtual(&props, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &props, + "java/util/Properties", + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; if encoding.is_null() { JavaLangString::from_rust_string(jvm, "UTF-8").await?.into() @@ -294,9 +300,9 @@ impl PrintStream { Self::with_monitor(jvm, &this, async { let out: ClassInstanceRef = jvm.get_field(&this, "out", "Ljava/io/OutputStream;").await?; if !out.is_null() { - let _: () = jvm.invoke_virtual(&this, "flush", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintStream", "flush", "()V", ()).await?; if jvm.is_instance(&**out, "java/io/PrintStream") { - return jvm.invoke_virtual(&out, "checkError", "()Z", ()).await; + return jvm.invoke_virtual(&out, "java/io/PrintStream", "checkError", "()Z", ()).await; } } jvm.get_field(&this, "trouble", "Z").await @@ -320,7 +326,7 @@ impl PrintStream { let mut this = this.clone(); jvm.put_field(&mut this, "closing", "Z", true).await?; let char_out: ClassInstanceRef = jvm.get_field(&this, "charOut", "Ljava/io/OutputStreamWriter;").await?; - let char_out_result = jvm.invoke_virtual(&char_out, "close", "()V", ()).await; + let char_out_result = jvm.invoke_virtual(&char_out, "java/io/OutputStreamWriter", "close", "()V", ()).await; let close_out = match char_out_result { Ok(()) => true, Err(JavaError::JavaException(exception)) if jvm.is_instance(&*exception, "java/io/IOException") => { @@ -331,7 +337,7 @@ impl PrintStream { }; if close_out { - match jvm.invoke_virtual(&out, "close", "()V", ()).await { + match jvm.invoke_virtual(&out, "java/io/OutputStream", "close", "()V", ()).await { Ok(()) => {} Err(JavaError::JavaException(exception)) if jvm.is_instance(&*exception, "java/io/IOException") => { jvm.put_field(&mut this, "trouble", "Z", true).await?; @@ -359,7 +365,7 @@ impl PrintStream { return Ok(()); } - let result = jvm.invoke_virtual(&out, "flush", "()V", ()).await; + let result = jvm.invoke_virtual(&out, "java/io/OutputStream", "flush", "()V", ()).await; Self::suppress_io_exception(jvm, &this, result).await.map(|_| ()) }) .await @@ -376,12 +382,12 @@ impl PrintStream { return Ok(()); } - let result = jvm.invoke_virtual(&out, "write", "(I)V", (value,)).await; + let result = jvm.invoke_virtual(&out, "java/io/OutputStream", "write", "(I)V", (value,)).await; if Self::suppress_io_exception(jvm, &this, result).await? && value == b'\n' as i32 && jvm.get_field::(&this, "autoFlush", "Z").await? { - let result = jvm.invoke_virtual(&out, "flush", "()V", ()).await; + let result = jvm.invoke_virtual(&out, "java/io/OutputStream", "flush", "()V", ()).await; Self::suppress_io_exception(jvm, &this, result).await?; } Ok(()) @@ -415,9 +421,11 @@ impl PrintStream { return Ok(()); } - let result = jvm.invoke_virtual(&out, "write", "([BII)V", (bytes, off, len)).await; + let result = jvm + .invoke_virtual(&out, "java/io/OutputStream", "write", "([BII)V", (bytes, off, len)) + .await; if Self::suppress_io_exception(jvm, &this, result).await? && jvm.get_field::(&this, "autoFlush", "Z").await? { - let result = jvm.invoke_virtual(&out, "flush", "()V", ()).await; + let result = jvm.invoke_virtual(&out, "java/io/OutputStream", "flush", "()V", ()).await; Self::suppress_io_exception(jvm, &this, result).await?; } Ok(()) @@ -497,7 +505,9 @@ impl PrintStream { .invoke_static("java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;", (value,)) .await?; Self::with_monitor(jvm, &this, async { - let _: () = jvm.invoke_virtual(&this, "print", "(Ljava/lang/String;)V", (value,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", (value,)) + .await?; Self::new_line(jvm, &this).await }) .await @@ -505,7 +515,9 @@ impl PrintStream { async fn println_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result<()> { Self::with_monitor(jvm, &this, async { - let _: () = jvm.invoke_virtual(&this, "print", "(Ljava/lang/String;)V", (value,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", (value,)) + .await?; Self::new_line(jvm, &this).await }) .await @@ -513,7 +525,7 @@ impl PrintStream { async fn println_int(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: i32) -> Result<()> { Self::with_monitor(jvm, &this, async { - let _: () = jvm.invoke_virtual(&this, "print", "(I)V", (value,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintStream", "print", "(I)V", (value,)).await?; Self::new_line(jvm, &this).await }) .await @@ -521,7 +533,7 @@ impl PrintStream { async fn println_long(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: i64) -> Result<()> { Self::with_monitor(jvm, &this, async { - let _: () = jvm.invoke_virtual(&this, "print", "(J)V", (value,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintStream", "print", "(J)V", (value,)).await?; Self::new_line(jvm, &this).await }) .await @@ -529,7 +541,7 @@ impl PrintStream { async fn println_char(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: JavaChar) -> Result<()> { Self::with_monitor(jvm, &this, async { - let _: () = jvm.invoke_virtual(&this, "print", "(C)V", (value,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintStream", "print", "(C)V", (value,)).await?; Self::new_line(jvm, &this).await }) .await @@ -537,7 +549,7 @@ impl PrintStream { async fn println_chars(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef>) -> Result<()> { Self::with_monitor(jvm, &this, async { - let _: () = jvm.invoke_virtual(&this, "print", "([C)V", (value,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintStream", "print", "([C)V", (value,)).await?; Self::new_line(jvm, &this).await }) .await @@ -545,7 +557,7 @@ impl PrintStream { async fn println_bool(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: bool) -> Result<()> { Self::with_monitor(jvm, &this, async { - let _: () = jvm.invoke_virtual(&this, "print", "(Z)V", (value,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintStream", "print", "(Z)V", (value,)).await?; Self::new_line(jvm, &this).await }) .await @@ -553,7 +565,7 @@ impl PrintStream { async fn println_float(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f32) -> Result<()> { Self::with_monitor(jvm, &this, async { - let _: () = jvm.invoke_virtual(&this, "print", "(F)V", (value,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintStream", "print", "(F)V", (value,)).await?; Self::new_line(jvm, &this).await }) .await @@ -561,7 +573,7 @@ impl PrintStream { async fn println_double(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f64) -> Result<()> { Self::with_monitor(jvm, &this, async { - let _: () = jvm.invoke_virtual(&this, "print", "(D)V", (value,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintStream", "print", "(D)V", (value,)).await?; Self::new_line(jvm, &this).await }) .await @@ -576,6 +588,7 @@ impl PrintStream { ) -> Result> { jvm.invoke_virtual( &this, + "java/io/PrintStream", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;", (format, arguments), @@ -593,6 +606,7 @@ impl PrintStream { ) -> Result> { jvm.invoke_virtual( &this, + "java/io/PrintStream", "format", "(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;", (locale, format, arguments), @@ -610,6 +624,7 @@ impl PrintStream { let locale: ClassInstanceRef = jvm.invoke_static("java/util/Locale", "getDefault", "()Ljava/util/Locale;", ()).await?; jvm.invoke_virtual( &this, + "java/io/PrintStream", "format", "(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;", (locale, format, arguments), @@ -634,6 +649,7 @@ impl PrintStream { let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + "java/util/Formatter", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), @@ -653,9 +669,12 @@ impl PrintStream { let string: ClassInstanceRef = if sequence.is_null() { JavaLangString::from_rust_string(jvm, "null").await?.into() } else { - jvm.invoke_virtual(&sequence, "toString", "()Ljava/lang/String;", ()).await? + jvm.invoke_virtual(&sequence, &sequence.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await? }; - let _: () = jvm.invoke_virtual(&this, "print", "(Ljava/lang/String;)V", (string,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", (string,)) + .await?; Ok(this) } @@ -673,20 +692,36 @@ impl PrintStream { sequence }; let subsequence: ClassInstanceRef = jvm - .invoke_virtual(&sequence, "subSequence", "(II)Ljava/lang/CharSequence;", (start, end)) + .invoke_virtual( + &sequence, + &sequence.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (start, end), + ) + .await?; + let string: ClassInstanceRef = jvm + .invoke_virtual( + &subsequence, + &subsequence.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", (string,)) .await?; - let string: ClassInstanceRef = jvm.invoke_virtual(&subsequence, "toString", "()Ljava/lang/String;", ()).await?; - let _: () = jvm.invoke_virtual(&this, "print", "(Ljava/lang/String;)V", (string,)).await?; Ok(this) } async fn append_char(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, character: JavaChar) -> Result> { - let _: () = jvm.invoke_virtual(&this, "print", "(C)V", (character,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintStream", "print", "(C)V", (character,)).await?; Ok(this) } async fn write_string(jvm: &Jvm, this: &ClassInstanceRef, value: ClassInstanceRef) -> Result<()> { - let chars: ClassInstanceRef> = jvm.invoke_virtual(&value, "toCharArray", "()[C", ()).await?; + let chars: ClassInstanceRef> = jvm.invoke_virtual(&value, "java/lang/String", "toCharArray", "()[C", ()).await?; Self::write_characters(jvm, this, chars).await } @@ -706,13 +741,15 @@ impl PrintStream { let length = jvm.array_length(&chars).await?; let values: Vec = jvm.load_array(&chars, 0, length).await?; let char_out: ClassInstanceRef = jvm.get_field(this, "charOut", "Ljava/io/OutputStreamWriter;").await?; - let result = jvm.invoke_virtual(&char_out, "write", "([CII)V", (chars, 0, length as i32)).await; + let result = jvm + .invoke_virtual(&char_out, "java/io/OutputStreamWriter", "write", "([CII)V", (chars, 0, length as i32)) + .await; if !Self::suppress_io_exception(jvm, this, result).await? { return Ok(()); } if jvm.get_field::(this, "autoFlush", "Z").await? && values.contains(&('\n' as JavaChar)) { - let result = jvm.invoke_virtual(&out, "flush", "()V", ()).await; + let result = jvm.invoke_virtual(&out, "java/io/OutputStream", "flush", "()V", ()).await; Self::suppress_io_exception(jvm, this, result).await?; } Ok(()) @@ -738,16 +775,18 @@ impl PrintStream { } else { separator }; - let chars: ClassInstanceRef> = jvm.invoke_virtual(&separator, "toCharArray", "()[C", ()).await?; + let chars: ClassInstanceRef> = jvm.invoke_virtual(&separator, "java/lang/String", "toCharArray", "()[C", ()).await?; let length = jvm.array_length(&chars).await?; let char_out: ClassInstanceRef = jvm.get_field(this, "charOut", "Ljava/io/OutputStreamWriter;").await?; - let result = jvm.invoke_virtual(&char_out, "write", "([CII)V", (chars, 0, length as i32)).await; + let result = jvm + .invoke_virtual(&char_out, "java/io/OutputStreamWriter", "write", "([CII)V", (chars, 0, length as i32)) + .await; if !Self::suppress_io_exception(jvm, this, result).await? { return Ok(()); } if jvm.get_field::(this, "autoFlush", "Z").await? { - let result = jvm.invoke_virtual(&out, "flush", "()V", ()).await; + let result = jvm.invoke_virtual(&out, "java/io/OutputStream", "flush", "()V", ()).await; Self::suppress_io_exception(jvm, this, result).await?; } Ok(()) diff --git a/java_runtime/src/classes/java/io/print_writer.rs b/java_runtime/src/classes/java/io/print_writer.rs index 8165e9ab..d264b706 100644 --- a/java_runtime/src/classes/java/io/print_writer.rs +++ b/java_runtime/src/classes/java/io/print_writer.rs @@ -314,7 +314,7 @@ impl PrintWriter { return Ok(()); } - let result = jvm.invoke_virtual(&out, "write", "(I)V", (value,)).await; + let result = jvm.invoke_virtual(&out, "java/io/Writer", "write", "(I)V", (value,)).await; Self::suppress_io_exception(jvm, &this, result).await }) .await @@ -329,7 +329,8 @@ impl PrintWriter { return Err(jvm.exception("java/lang/NullPointerException", "chars is null").await); } let length = jvm.array_length(&chars).await? as i32; - jvm.invoke_virtual(&this, "write", "([CII)V", (chars, 0, length)).await + jvm.invoke_virtual(&this, "java/io/PrintWriter", "write", "([CII)V", (chars, 0, length)) + .await }) .await } @@ -361,7 +362,9 @@ impl PrintWriter { return Ok(()); } - let result = jvm.invoke_virtual(&out, "write", "([CII)V", (chars, offset, length)).await; + let result = jvm + .invoke_virtual(&out, "java/io/Writer", "write", "([CII)V", (chars, offset, length)) + .await; Self::suppress_io_exception(jvm, &this, result).await }) .await @@ -375,8 +378,9 @@ impl PrintWriter { if string.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "string is null").await); } - let length: i32 = jvm.invoke_virtual(&string, "length", "()I", ()).await?; - jvm.invoke_virtual(&this, "write", "(Ljava/lang/String;II)V", (string, 0, length)).await + let length: i32 = jvm.invoke_virtual(&string, "java/lang/String", "length", "()I", ()).await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "write", "(Ljava/lang/String;II)V", (string, 0, length)) + .await }) .await } @@ -396,7 +400,7 @@ impl PrintWriter { if string.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "string is null").await); } - let string_length: i32 = jvm.invoke_virtual(&string, "length", "()I", ()).await?; + let string_length: i32 = jvm.invoke_virtual(&string, "java/lang/String", "length", "()I", ()).await?; if offset < 0 || length < 0 || offset > string_length - length { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "invalid offset or length").await); } @@ -409,7 +413,7 @@ impl PrintWriter { } let result = jvm - .invoke_virtual(&out, "write", "(Ljava/lang/String;II)V", (string, offset, length)) + .invoke_virtual(&out, "java/io/Writer", "write", "(Ljava/lang/String;II)V", (string, offset, length)) .await; Self::suppress_io_exception(jvm, &this, result).await }) @@ -426,7 +430,7 @@ impl PrintWriter { async fn print_char(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: JavaChar) -> Result<()> { tracing::debug!("java.io.PrintWriter::print({this:?}, {value})"); - jvm.invoke_virtual(&this, "write", "(I)V", (value as i32,)).await + jvm.invoke_virtual(&this, "java/io/PrintWriter", "write", "(I)V", (value as i32,)).await } async fn print_int(jvm: &Jvm, context: &mut RuntimeContext, this: ClassInstanceRef, value: i32) -> Result<()> { @@ -463,7 +467,7 @@ impl PrintWriter { async fn print_chars(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef>) -> Result<()> { tracing::debug!("java.io.PrintWriter::print({this:?}, {value:?})"); - jvm.invoke_virtual(&this, "write", "([C)V", (value,)).await + jvm.invoke_virtual(&this, "java/io/PrintWriter", "write", "([C)V", (value,)).await } async fn print_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result<()> { @@ -473,7 +477,8 @@ impl PrintWriter { } else { value }; - jvm.invoke_virtual(&this, "write", "(Ljava/lang/String;)V", (value,)).await + jvm.invoke_virtual(&this, "java/io/PrintWriter", "write", "(Ljava/lang/String;)V", (value,)) + .await } async fn print_object(jvm: &Jvm, context: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result<()> { @@ -505,7 +510,10 @@ impl PrintWriter { } else { separator }; - match jvm.invoke_virtual(&out, "write", "(Ljava/lang/String;)V", (separator,)).await { + match jvm + .invoke_virtual(&out, "java/io/Writer", "write", "(Ljava/lang/String;)V", (separator,)) + .await + { Ok(()) => {} Err(JavaError::JavaException(exception)) if jvm.is_instance(&*exception, "java/io/IOException") => { let mut this = this.clone(); @@ -516,7 +524,7 @@ impl PrintWriter { } if jvm.get_field::(&this, "autoFlush", "Z").await? { - let result = jvm.invoke_virtual(&out, "flush", "()V", ()).await; + let result = jvm.invoke_virtual(&out, "java/io/Writer", "flush", "()V", ()).await; Self::suppress_io_exception(jvm, &this, result).await } else { Ok(()) @@ -528,8 +536,8 @@ impl PrintWriter { async fn println_boolean(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: bool) -> Result<()> { let lock: ClassInstanceRef = jvm.get_field(&this, "lock", "Ljava/lang/Object;").await?; Self::with_lock(jvm, &lock, async { - let _: () = jvm.invoke_virtual(&this, "print", "(Z)V", (value,)).await?; - jvm.invoke_virtual(&this, "println", "()V", ()).await + let _: () = jvm.invoke_virtual(&this, "java/io/PrintWriter", "print", "(Z)V", (value,)).await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "println", "()V", ()).await }) .await } @@ -537,8 +545,8 @@ impl PrintWriter { async fn println_char(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: JavaChar) -> Result<()> { let lock: ClassInstanceRef = jvm.get_field(&this, "lock", "Ljava/lang/Object;").await?; Self::with_lock(jvm, &lock, async { - let _: () = jvm.invoke_virtual(&this, "print", "(C)V", (value,)).await?; - jvm.invoke_virtual(&this, "println", "()V", ()).await + let _: () = jvm.invoke_virtual(&this, "java/io/PrintWriter", "print", "(C)V", (value,)).await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "println", "()V", ()).await }) .await } @@ -546,8 +554,8 @@ impl PrintWriter { async fn println_int(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: i32) -> Result<()> { let lock: ClassInstanceRef = jvm.get_field(&this, "lock", "Ljava/lang/Object;").await?; Self::with_lock(jvm, &lock, async { - let _: () = jvm.invoke_virtual(&this, "print", "(I)V", (value,)).await?; - jvm.invoke_virtual(&this, "println", "()V", ()).await + let _: () = jvm.invoke_virtual(&this, "java/io/PrintWriter", "print", "(I)V", (value,)).await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "println", "()V", ()).await }) .await } @@ -555,8 +563,8 @@ impl PrintWriter { async fn println_long(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: i64) -> Result<()> { let lock: ClassInstanceRef = jvm.get_field(&this, "lock", "Ljava/lang/Object;").await?; Self::with_lock(jvm, &lock, async { - let _: () = jvm.invoke_virtual(&this, "print", "(J)V", (value,)).await?; - jvm.invoke_virtual(&this, "println", "()V", ()).await + let _: () = jvm.invoke_virtual(&this, "java/io/PrintWriter", "print", "(J)V", (value,)).await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "println", "()V", ()).await }) .await } @@ -564,8 +572,8 @@ impl PrintWriter { async fn println_float(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f32) -> Result<()> { let lock: ClassInstanceRef = jvm.get_field(&this, "lock", "Ljava/lang/Object;").await?; Self::with_lock(jvm, &lock, async { - let _: () = jvm.invoke_virtual(&this, "print", "(F)V", (value,)).await?; - jvm.invoke_virtual(&this, "println", "()V", ()).await + let _: () = jvm.invoke_virtual(&this, "java/io/PrintWriter", "print", "(F)V", (value,)).await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "println", "()V", ()).await }) .await } @@ -573,8 +581,8 @@ impl PrintWriter { async fn println_double(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f64) -> Result<()> { let lock: ClassInstanceRef = jvm.get_field(&this, "lock", "Ljava/lang/Object;").await?; Self::with_lock(jvm, &lock, async { - let _: () = jvm.invoke_virtual(&this, "print", "(D)V", (value,)).await?; - jvm.invoke_virtual(&this, "println", "()V", ()).await + let _: () = jvm.invoke_virtual(&this, "java/io/PrintWriter", "print", "(D)V", (value,)).await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "println", "()V", ()).await }) .await } @@ -582,8 +590,8 @@ impl PrintWriter { async fn println_chars(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef>) -> Result<()> { let lock: ClassInstanceRef = jvm.get_field(&this, "lock", "Ljava/lang/Object;").await?; Self::with_lock(jvm, &lock, async { - let _: () = jvm.invoke_virtual(&this, "print", "([C)V", (value,)).await?; - jvm.invoke_virtual(&this, "println", "()V", ()).await + let _: () = jvm.invoke_virtual(&this, "java/io/PrintWriter", "print", "([C)V", (value,)).await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "println", "()V", ()).await }) .await } @@ -591,8 +599,10 @@ impl PrintWriter { async fn println_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result<()> { let lock: ClassInstanceRef = jvm.get_field(&this, "lock", "Ljava/lang/Object;").await?; Self::with_lock(jvm, &lock, async { - let _: () = jvm.invoke_virtual(&this, "print", "(Ljava/lang/String;)V", (value,)).await?; - jvm.invoke_virtual(&this, "println", "()V", ()).await + let _: () = jvm + .invoke_virtual(&this, "java/io/PrintWriter", "print", "(Ljava/lang/String;)V", (value,)) + .await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "println", "()V", ()).await }) .await } @@ -600,8 +610,10 @@ impl PrintWriter { async fn println_object(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result<()> { let lock: ClassInstanceRef = jvm.get_field(&this, "lock", "Ljava/lang/Object;").await?; Self::with_lock(jvm, &lock, async { - let _: () = jvm.invoke_virtual(&this, "print", "(Ljava/lang/Object;)V", (value,)).await?; - jvm.invoke_virtual(&this, "println", "()V", ()).await + let _: () = jvm + .invoke_virtual(&this, "java/io/PrintWriter", "print", "(Ljava/lang/Object;)V", (value,)) + .await?; + jvm.invoke_virtual(&this, "java/io/PrintWriter", "println", "()V", ()).await }) .await } @@ -618,7 +630,7 @@ impl PrintWriter { return Ok(()); } - let result = jvm.invoke_virtual(&out, "flush", "()V", ()).await; + let result = jvm.invoke_virtual(&out, "java/io/Writer", "flush", "()V", ()).await; Self::suppress_io_exception(jvm, &this, result).await }) .await @@ -634,7 +646,7 @@ impl PrintWriter { return Ok(()); } - match jvm.invoke_virtual(&out, "close", "()V", ()).await { + match jvm.invoke_virtual(&out, "java/io/Writer", "close", "()V", ()).await { Ok(()) => { let mut this = this.clone(); let closed: ClassInstanceRef = None.into(); @@ -657,9 +669,9 @@ impl PrintWriter { Self::with_lock(jvm, &lock, async { let out: ClassInstanceRef = jvm.get_field(&this, "out", "Ljava/io/Writer;").await?; if !out.is_null() { - let _: () = jvm.invoke_virtual(&this, "flush", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintWriter", "flush", "()V", ()).await?; if jvm.is_instance(&**out, "java/io/PrintWriter") { - return jvm.invoke_virtual(&out, "checkError", "()Z", ()).await; + return jvm.invoke_virtual(&out, "java/io/PrintWriter", "checkError", "()Z", ()).await; } } jvm.get_field(&this, "trouble", "Z").await @@ -680,6 +692,7 @@ impl PrintWriter { ) -> Result> { jvm.invoke_virtual( &this, + "java/io/PrintWriter", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;", (format, arguments), @@ -697,6 +710,7 @@ impl PrintWriter { ) -> Result> { jvm.invoke_virtual( &this, + "java/io/PrintWriter", "format", "(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;", (locale, format, arguments), @@ -714,6 +728,7 @@ impl PrintWriter { let locale: ClassInstanceRef = jvm.invoke_static("java/util/Locale", "getDefault", "()Ljava/util/Locale;", ()).await?; jvm.invoke_virtual( &this, + "java/io/PrintWriter", "format", "(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;", (locale, format, arguments), @@ -739,13 +754,14 @@ impl PrintWriter { let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + "java/util/Formatter", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; if jvm.get_field::(&this, "autoFlush", "Z").await? { - let _: () = jvm.invoke_virtual(&this, "flush", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/PrintWriter", "flush", "()V", ()).await?; } Ok(this.clone()) }) diff --git a/java_runtime/src/classes/java/io/random_access_file.rs b/java_runtime/src/classes/java/io/random_access_file.rs index 4f4801d9..68fc1a08 100644 --- a/java_runtime/src/classes/java/io/random_access_file.rs +++ b/java_runtime/src/classes/java/io/random_access_file.rs @@ -3,6 +3,7 @@ use alloc::vec; use bytemuck::cast_vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -23,21 +24,31 @@ impl RandomAccessFile { parent_class: Some("java/lang/Object"), interfaces: vec!["java/io/DataInput", "java/io/DataOutput"], methods: vec![ - JavaMethodProto::new("", "(Ljava/lang/String;Ljava/lang/String;)V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/io/File;Ljava/lang/String;)V", Self::init_with_file, Default::default()), - JavaMethodProto::new("read", "([B)I", Self::read, Default::default()), - JavaMethodProto::new("read", "([BII)I", Self::read_offset_length, Default::default()), - JavaMethodProto::new("write", "([B)V", Self::write, Default::default()), - JavaMethodProto::new("write", "([BII)V", Self::write_offset_length, Default::default()), - JavaMethodProto::new("length", "()J", Self::length, Default::default()), - JavaMethodProto::new("getFilePointer", "()J", Self::get_file_pointer, Default::default()), - JavaMethodProto::new("getFD", "()Ljava/io/FileDescriptor;", Self::get_fd, Default::default()), - JavaMethodProto::new("seek", "(J)V", Self::seek, Default::default()), - JavaMethodProto::new("setLength", "(J)V", Self::set_length, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), + JavaMethodProto::new("", "(Ljava/lang/String;Ljava/lang/String;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "", + "(Ljava/io/File;Ljava/lang/String;)V", + Self::init_with_file, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new("read", "([B)I", Self::read, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "([BII)I", Self::read_offset_length, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("write", "([B)V", Self::write, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("write", "([BII)V", Self::write_offset_length, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("length", "()J", Self::length, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getFilePointer", "()J", Self::get_file_pointer, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "getFD", + "()Ljava/io/FileDescriptor;", + Self::get_fd, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new("seek", "(J)V", Self::seek, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("setLength", "(J)V", Self::set_length, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("fd", "Ljava/io/FileDescriptor;", Default::default())], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -86,7 +97,7 @@ impl RandomAccessFile { ) -> Result<()> { tracing::debug!("java.io.RandomAccessFile::({this:?}, {file:?}, {mode:?})"); - let name: ClassInstanceRef = jvm.invoke_virtual(&file, "getPath", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm.invoke_virtual(&file, "java/io/File", "getPath", "()Ljava/lang/String;", ()).await?; let _: () = jvm .invoke_special( @@ -105,7 +116,9 @@ impl RandomAccessFile { tracing::debug!("java.io.RandomAccessFile::read({this:?}, {buf:?})"); let length = jvm.array_length(&buf).await?; - let read = jvm.invoke_virtual(&this, "read", "([BII)I", (buf, 0, length as i32)).await?; + let read = jvm + .invoke_virtual(&this, "java/io/RandomAccessFile", "read", "([BII)I", (buf, 0, length as i32)) + .await?; Ok(read) } @@ -137,7 +150,9 @@ impl RandomAccessFile { tracing::debug!("java.io.RandomAccessFile::write({this:?}, {buf:?})"); let length = jvm.array_length(&buf).await?; - let _: () = jvm.invoke_virtual(&this, "write", "([BII)V", (buf, 0, length as i32)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/RandomAccessFile", "write", "([BII)V", (buf, 0, length as i32)) + .await?; Ok(()) } diff --git a/java_runtime/src/classes/java/io/reader.rs b/java_runtime/src/classes/java/io/reader.rs index 2a13b18f..39f13a50 100644 --- a/java_runtime/src/classes/java/io/reader.rs +++ b/java_runtime/src/classes/java/io/reader.rs @@ -18,15 +18,15 @@ impl Reader { methods: vec![ JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PROTECTED), JavaMethodProto::new("", "(Ljava/lang/Object;)V", Self::init_with_lock, MethodAccessFlags::PROTECTED), - JavaMethodProto::new("read", "()I", Self::read_char, Default::default()), - JavaMethodProto::new("read", "([C)I", Self::read, Default::default()), - JavaMethodProto::new_abstract("read", "([CII)I", Default::default()), - JavaMethodProto::new("skip", "(J)J", Self::skip, Default::default()), - JavaMethodProto::new("ready", "()Z", Self::ready, Default::default()), - JavaMethodProto::new("markSupported", "()Z", Self::mark_supported, Default::default()), - JavaMethodProto::new("mark", "(I)V", Self::mark, Default::default()), - JavaMethodProto::new("reset", "()V", Self::reset, Default::default()), - JavaMethodProto::new_abstract("close", "()V", Default::default()), + JavaMethodProto::new("read", "()I", Self::read_char, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "([C)I", Self::read, MethodAccessFlags::PUBLIC), + JavaMethodProto::new_abstract("read", "([CII)I", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new("skip", "(J)J", Self::skip, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("ready", "()Z", Self::ready, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("markSupported", "()Z", Self::mark_supported, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("mark", "(I)V", Self::mark, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("reset", "()V", Self::reset, MethodAccessFlags::PUBLIC), + JavaMethodProto::new_abstract("close", "()V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), ], fields: vec![JavaFieldProto::new("lock", "Ljava/lang/Object;", FieldAccessFlags::PROTECTED)], access_flags: ClassAccessFlags::ABSTRACT, @@ -60,7 +60,9 @@ impl Reader { tracing::debug!("java.io.Reader::read({this:?})"); let chars = jvm.instantiate_array("C", 1).await?; - let read: i32 = jvm.invoke_virtual(&this, "read", "([CII)I", (chars.clone(), 0, 1)).await?; + let read: i32 = jvm + .invoke_virtual(&this, "java/io/Reader", "read", "([CII)I", (chars.clone(), 0, 1)) + .await?; if read == -1 { return Ok(-1); } @@ -73,7 +75,7 @@ impl Reader { tracing::debug!("java.io.Reader::read({this:?}, {buf:?})"); let len = jvm.array_length(&buf).await? as i32; - let result = jvm.invoke_virtual(&this, "read", "([CII)I", (buf, 0, len)).await?; + let result = jvm.invoke_virtual(&this, "java/io/Reader", "read", "([CII)I", (buf, 0, len)).await?; Ok(result) } @@ -90,7 +92,13 @@ impl Reader { let mut remaining = n; while remaining > 0 { let read: i32 = jvm - .invoke_virtual(&this, "read", "([CII)I", (buffer.clone(), 0, remaining.min(buffer_size as i64) as i32)) + .invoke_virtual( + &this, + "java/io/Reader", + "read", + "([CII)I", + (buffer.clone(), 0, remaining.min(buffer_size as i64) as i32), + ) .await?; if read == -1 { break; diff --git a/java_runtime/src/classes/java/io/string_reader.rs b/java_runtime/src/classes/java/io/string_reader.rs index 4e8c7be7..4b200824 100644 --- a/java_runtime/src/classes/java/io/string_reader.rs +++ b/java_runtime/src/classes/java/io/string_reader.rs @@ -48,7 +48,7 @@ impl StringReader { return Err(jvm.exception("java/lang/NullPointerException", "string is null").await); } let _: () = jvm.invoke_special(&this, "java/io/Reader", "", "()V", ()).await?; - let length: i32 = jvm.invoke_virtual(&value, "length", "()I", ()).await?; + let length: i32 = jvm.invoke_virtual(&value, "java/lang/String", "length", "()I", ()).await?; jvm.put_field(&mut this, "str", "Ljava/lang/String;", value).await?; jvm.put_field(&mut this, "length", "I", length).await?; jvm.put_field(&mut this, "next", "I", 0).await?; @@ -91,7 +91,7 @@ impl StringReader { if next >= length { return Ok(-1); } - let result: JavaChar = jvm.invoke_virtual(&value, "charAt", "(I)C", (next,)).await?; + let result: JavaChar = jvm.invoke_virtual(&value, "java/lang/String", "charAt", "(I)C", (next,)).await?; jvm.put_field(&mut this, "next", "I", next + 1).await?; Ok(result as i32) } @@ -139,7 +139,7 @@ impl StringReader { } let copied = length.min(source_length - next); let _: () = jvm - .invoke_virtual(&value, "getChars", "(II[CI)V", (next, next + copied, target, offset)) + .invoke_virtual(&value, "java/lang/String", "getChars", "(II[CI)V", (next, next + copied, target, offset)) .await?; jvm.put_field(&mut this, "next", "I", next + copied).await?; Ok(copied) diff --git a/java_runtime/src/classes/java/io/string_writer.rs b/java_runtime/src/classes/java/io/string_writer.rs index 328a775d..fc82ba33 100644 --- a/java_runtime/src/classes/java/io/string_writer.rs +++ b/java_runtime/src/classes/java/io/string_writer.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaChar, Jvm, Result}; use crate::{ @@ -18,14 +19,14 @@ impl StringWriter { parent_class: Some("java/io/Writer"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("write", "([CII)V", Self::write, Default::default()), - JavaMethodProto::new("flush", "()V", Self::flush, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), - JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("write", "([CII)V", Self::write, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("flush", "()V", Self::flush, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("buf", "Ljava/lang/StringBuffer;", Default::default())], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -53,7 +54,13 @@ impl StringWriter { let buf = jvm.get_field(&this, "buf", "Ljava/lang/StringBuffer;").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buf, "append", "([CII)Ljava/lang/StringBuffer;", (chars, off, len)) + .invoke_virtual( + &buf, + "java/lang/StringBuffer", + "append", + "([CII)Ljava/lang/StringBuffer;", + (chars, off, len), + ) .await?; Ok(()) @@ -74,7 +81,9 @@ impl StringWriter { let buf = jvm.get_field(&this, "buf", "Ljava/lang/StringBuffer;").await?; - let string = jvm.invoke_virtual(&buf, "toString", "()Ljava/lang/String;", ()).await?; + let string = jvm + .invoke_virtual(&buf, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; Ok(string) } diff --git a/java_runtime/src/classes/java/io/writer.rs b/java_runtime/src/classes/java/io/writer.rs index 208ea58a..bb90f0b4 100644 --- a/java_runtime/src/classes/java/io/writer.rs +++ b/java_runtime/src/classes/java/io/writer.rs @@ -93,23 +93,25 @@ impl Writer { let mut chars = jvm.instantiate_array("C", 1).await?; jvm.store_array(&mut chars, 0, [value as JavaChar]).await?; - jvm.invoke_virtual(&this, "write", "([CII)V", (chars, 0, 1)).await + jvm.invoke_virtual(&this, "java/io/Writer", "write", "([CII)V", (chars, 0, 1)).await } async fn write_chars(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, chars: ClassInstanceRef>) -> Result<()> { tracing::debug!("java.io.Writer::write({this:?}, {chars:?})"); let length = jvm.array_length(&chars).await? as i32; - jvm.invoke_virtual(&this, "write", "([CII)V", (chars, 0, length)).await + jvm.invoke_virtual(&this, "java/io/Writer", "write", "([CII)V", (chars, 0, length)).await } async fn write_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, string: ClassInstanceRef) -> Result<()> { tracing::debug!("java.io.Writer::write_string({this:?}, {string:?})"); - let chars: ClassInstanceRef> = jvm.invoke_virtual(&string, "toCharArray", "()[C", ()).await?; + let chars: ClassInstanceRef> = jvm.invoke_virtual(&string, "java/lang/String", "toCharArray", "()[C", ()).await?; let length = jvm.array_length(&chars).await?; - let _: () = jvm.invoke_virtual(&this, "write", "([CII)V", (chars, 0, length as i32)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/Writer", "write", "([CII)V", (chars, 0, length as i32)) + .await?; Ok(()) } @@ -124,8 +126,8 @@ impl Writer { ) -> Result<()> { tracing::debug!("java.io.Writer::write({this:?}, {string:?}, {off}, {len})"); - let chars: ClassInstanceRef> = jvm.invoke_virtual(&string, "toCharArray", "()[C", ()).await?; - jvm.invoke_virtual(&this, "write", "([CII)V", (chars, off, len)).await + let chars: ClassInstanceRef> = jvm.invoke_virtual(&string, "java/lang/String", "toCharArray", "()[C", ()).await?; + jvm.invoke_virtual(&this, "java/io/Writer", "write", "([CII)V", (chars, off, len)).await } async fn append_char_sequence( @@ -137,9 +139,12 @@ impl Writer { let string: ClassInstanceRef = if sequence.is_null() { JavaLangString::from_rust_string(jvm, "null").await?.into() } else { - jvm.invoke_virtual(&sequence, "toString", "()Ljava/lang/String;", ()).await? + jvm.invoke_virtual(&sequence, &sequence.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await? }; - let _: () = jvm.invoke_virtual(&this, "write", "(Ljava/lang/String;)V", (string,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/Writer", "write", "(Ljava/lang/String;)V", (string,)) + .await?; Ok(this) } @@ -157,15 +162,31 @@ impl Writer { sequence }; let subsequence: ClassInstanceRef = jvm - .invoke_virtual(&sequence, "subSequence", "(II)Ljava/lang/CharSequence;", (start, end)) + .invoke_virtual( + &sequence, + &sequence.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (start, end), + ) + .await?; + let string: ClassInstanceRef = jvm + .invoke_virtual( + &subsequence, + &subsequence.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; + let _: () = jvm + .invoke_virtual(&this, "java/io/Writer", "write", "(Ljava/lang/String;)V", (string,)) .await?; - let string: ClassInstanceRef = jvm.invoke_virtual(&subsequence, "toString", "()Ljava/lang/String;", ()).await?; - let _: () = jvm.invoke_virtual(&this, "write", "(Ljava/lang/String;)V", (string,)).await?; Ok(this) } async fn append_char(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, character: JavaChar) -> Result> { - let _: () = jvm.invoke_virtual(&this, "write", "(I)V", (character as i32,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/io/Writer", "write", "(I)V", (character as i32,)).await?; Ok(this) } } diff --git a/java_runtime/src/classes/java/lang/abstract_string_builder.rs b/java_runtime/src/classes/java/lang/abstract_string_builder.rs index 1296bec7..88cee38a 100644 --- a/java_runtime/src/classes/java/lang/abstract_string_builder.rs +++ b/java_runtime/src/classes/java/lang/abstract_string_builder.rs @@ -303,10 +303,15 @@ impl AbstractStringBuilder { if jvm.is_instance(&***sequence, "java/lang/String") { return JavaLangString::to_utf16(jvm, sequence).await; } - let length: i32 = jvm.invoke_virtual(sequence, "length", "()I", ()).await?; + let length: i32 = jvm + .invoke_virtual(sequence, &sequence.class_definition().name(), "length", "()I", ()) + .await?; let mut characters = Vec::with_capacity(length as usize); for index in 0..length { - characters.push(jvm.invoke_virtual(sequence, "charAt", "(I)C", (index,)).await?); + characters.push( + jvm.invoke_virtual(sequence, &sequence.class_definition().name(), "charAt", "(I)C", (index,)) + .await?, + ); } Ok(characters) } @@ -506,10 +511,17 @@ impl AbstractStringBuilder { let string: ClassInstanceRef = if object.is_null() { JavaLangString::from_rust_string(jvm, "null").await?.into() } else { - jvm.invoke_virtual(&object, "toString", "()Ljava/lang/String;", ()).await? + jvm.invoke_virtual(&object, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await? }; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "append", + "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", + (string,), + ) + .await } async fn append_string( @@ -537,10 +549,17 @@ impl AbstractStringBuilder { let string: ClassInstanceRef = if buffer.is_null() { JavaLangString::from_rust_string(jvm, "null").await?.into() } else { - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await? + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await? }; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "append", + "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", + (string,), + ) + .await } async fn append_char_sequence( @@ -583,8 +602,14 @@ impl AbstractStringBuilder { return Err(jvm.exception("java/lang/NullPointerException", "str is null").await); } let length = jvm.array_length(&array).await? as i32; - jvm.invoke_virtual(&this, "append", "([CII)Ljava/lang/AbstractStringBuilder;", (array, 0, length)) - .await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "append", + "([CII)Ljava/lang/AbstractStringBuilder;", + (array, 0, length), + ) + .await } async fn append_char_array_range( @@ -610,8 +635,14 @@ impl AbstractStringBuilder { async fn append_boolean(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: bool) -> Result> { let string = JavaLangString::from_rust_string(jvm, if value { "true" } else { "false" }).await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "append", + "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", + (string,), + ) + .await } async fn append_char(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, value: JavaChar) -> Result> { @@ -623,30 +654,54 @@ impl AbstractStringBuilder { async fn append_int(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: i32) -> Result> { let string = JavaLangString::from_rust_string(jvm, &value.to_string()).await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "append", + "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", + (string,), + ) + .await } async fn append_long(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: i64) -> Result> { let string = JavaLangString::from_rust_string(jvm, &value.to_string()).await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "append", + "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", + (string,), + ) + .await } async fn append_float(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f32) -> Result> { let string: ClassInstanceRef = jvm .invoke_static("java/lang/Float", "toString", "(F)Ljava/lang/String;", (value,)) .await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "append", + "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", + (string,), + ) + .await } async fn append_double(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f64) -> Result> { let string: ClassInstanceRef = jvm .invoke_static("java/lang/Double", "toString", "(D)Ljava/lang/String;", (value,)) .await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "append", + "(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;", + (string,), + ) + .await } async fn append_code_point( @@ -714,7 +769,14 @@ impl AbstractStringBuilder { async fn substring(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, start: i32) -> Result> { let count: i32 = jvm.get_field(&this, "count", "I").await?; - jvm.invoke_virtual(&this, "substring", "(II)Ljava/lang/String;", (start, count)).await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "substring", + "(II)Ljava/lang/String;", + (start, count), + ) + .await } async fn substring_range( @@ -742,7 +804,14 @@ impl AbstractStringBuilder { start: i32, end: i32, ) -> Result> { - jvm.invoke_virtual(&this, "substring", "(II)Ljava/lang/String;", (start, end)).await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "substring", + "(II)Ljava/lang/String;", + (start, end), + ) + .await } async fn insert_char_array_range( @@ -776,10 +845,12 @@ impl AbstractStringBuilder { let string: ClassInstanceRef = if object.is_null() { JavaLangString::from_rust_string(jvm, "null").await?.into() } else { - jvm.invoke_virtual(&object, "toString", "()Ljava/lang/String;", ()).await? + jvm.invoke_virtual(&object, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await? }; jvm.invoke_virtual( &this, + "java/lang/AbstractStringBuilder", "insert", "(ILjava/lang/String;)Ljava/lang/AbstractStringBuilder;", (offset, string), @@ -814,8 +885,14 @@ impl AbstractStringBuilder { return Err(jvm.exception("java/lang/NullPointerException", "str is null").await); } let length = jvm.array_length(&array).await? as i32; - jvm.invoke_virtual(&this, "insert", "(I[CII)Ljava/lang/AbstractStringBuilder;", (offset, array, 0, length)) - .await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "insert", + "(I[CII)Ljava/lang/AbstractStringBuilder;", + (offset, array, 0, length), + ) + .await } async fn insert_char_sequence( @@ -857,6 +934,7 @@ impl AbstractStringBuilder { let string = JavaLangString::from_rust_string(jvm, if value { "true" } else { "false" }).await?; jvm.invoke_virtual( &this, + "java/lang/AbstractStringBuilder", "insert", "(ILjava/lang/String;)Ljava/lang/AbstractStringBuilder;", (offset, string), @@ -879,6 +957,7 @@ impl AbstractStringBuilder { let string = JavaLangString::from_rust_string(jvm, &value.to_string()).await?; jvm.invoke_virtual( &this, + "java/lang/AbstractStringBuilder", "insert", "(ILjava/lang/String;)Ljava/lang/AbstractStringBuilder;", (offset, string), @@ -890,6 +969,7 @@ impl AbstractStringBuilder { let string = JavaLangString::from_rust_string(jvm, &value.to_string()).await?; jvm.invoke_virtual( &this, + "java/lang/AbstractStringBuilder", "insert", "(ILjava/lang/String;)Ljava/lang/AbstractStringBuilder;", (offset, string), @@ -909,6 +989,7 @@ impl AbstractStringBuilder { .await?; jvm.invoke_virtual( &this, + "java/lang/AbstractStringBuilder", "insert", "(ILjava/lang/String;)Ljava/lang/AbstractStringBuilder;", (offset, string), @@ -928,6 +1009,7 @@ impl AbstractStringBuilder { .await?; jvm.invoke_virtual( &this, + "java/lang/AbstractStringBuilder", "insert", "(ILjava/lang/String;)Ljava/lang/AbstractStringBuilder;", (offset, string), @@ -936,7 +1018,8 @@ impl AbstractStringBuilder { } async fn index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, string: ClassInstanceRef) -> Result { - jvm.invoke_virtual(&this, "indexOf", "(Ljava/lang/String;I)I", (string, 0)).await + jvm.invoke_virtual(&this, "java/lang/AbstractStringBuilder", "indexOf", "(Ljava/lang/String;I)I", (string, 0)) + .await } async fn index_of_from( @@ -966,7 +1049,14 @@ impl AbstractStringBuilder { async fn last_index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, string: ClassInstanceRef) -> Result { let count: i32 = jvm.get_field(&this, "count", "I").await?; - jvm.invoke_virtual(&this, "lastIndexOf", "(Ljava/lang/String;I)I", (string, count)).await + jvm.invoke_virtual( + &this, + "java/lang/AbstractStringBuilder", + "lastIndexOf", + "(Ljava/lang/String;I)I", + (string, count), + ) + .await } async fn last_index_of_from( diff --git a/java_runtime/src/classes/java/lang/boolean.rs b/java_runtime/src/classes/java/lang/boolean.rs index 4bd6c99b..cab12dc3 100644 --- a/java_runtime/src/classes/java/lang/boolean.rs +++ b/java_runtime/src/classes/java/lang/boolean.rs @@ -126,12 +126,12 @@ impl Boolean { } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let value: bool = jvm.invoke_virtual(&this, "booleanValue", "()Z", ()).await?; + let value: bool = jvm.invoke_virtual(&this, "java/lang/Boolean", "booleanValue", "()Z", ()).await?; Ok(JavaLangString::from_rust_string(jvm, if value { "true" } else { "false" }).await?.into()) } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: bool = jvm.invoke_virtual(&this, "booleanValue", "()Z", ()).await?; + let value: bool = jvm.invoke_virtual(&this, "java/lang/Boolean", "booleanValue", "()Z", ()).await?; Ok(if value { 1231 } else { 1237 }) } @@ -140,8 +140,8 @@ impl Boolean { return Ok(false); } - let this_value: bool = jvm.invoke_virtual(&this, "booleanValue", "()Z", ()).await?; - let other_value: bool = jvm.invoke_virtual(&other, "booleanValue", "()Z", ()).await?; + let this_value: bool = jvm.invoke_virtual(&this, "java/lang/Boolean", "booleanValue", "()Z", ()).await?; + let other_value: bool = jvm.invoke_virtual(&other, "java/lang/Boolean", "booleanValue", "()Z", ()).await?; Ok(this_value == other_value) } diff --git a/java_runtime/src/classes/java/lang/byte.rs b/java_runtime/src/classes/java/lang/byte.rs index 82ccfa28..34db001c 100644 --- a/java_runtime/src/classes/java/lang/byte.rs +++ b/java_runtime/src/classes/java/lang/byte.rs @@ -169,7 +169,7 @@ impl Byte { let integer = jvm .invoke_static("java/lang/Integer", "decode", "(Ljava/lang/String;)Ljava/lang/Integer;", (value,)) .await?; - let value: i32 = jvm.invoke_virtual(&integer, "intValue", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&integer, "java/lang/Integer", "intValue", "()I", ()).await?; if !(i32::from(i8::MIN)..=i32::from(i8::MAX)).contains(&value) { return Err(jvm.exception("java/lang/NumberFormatException", "Value out of range").await); } @@ -181,32 +181,32 @@ impl Byte { } async fn short_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; + let value: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(value as i16) } async fn int_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; + let value: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(value as i32) } async fn long_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; + let value: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(value as i64) } async fn float_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; + let value: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(value as f32) } async fn double_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; + let value: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(value as f64) } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let value: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; + let value: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(JavaLangString::from_rust_string(jvm, &format!("{value}")).await?.into()) } @@ -215,7 +215,7 @@ impl Byte { } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; + let value: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(value as i32) } @@ -223,8 +223,8 @@ impl Byte { if other.is_null() || !jvm.is_instance(&**other, "java/lang/Byte") { return Ok(false); } - let left: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; - let right: i8 = jvm.invoke_virtual(&other, "byteValue", "()B", ()).await?; + let left: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; + let right: i8 = jvm.invoke_virtual(&other, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(left == right) } @@ -232,8 +232,8 @@ impl Byte { if other.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "other").await); } - let left: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; - let right: i8 = jvm.invoke_virtual(&other, "byteValue", "()B", ()).await?; + let left: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; + let right: i8 = jvm.invoke_virtual(&other, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(left.cmp(&right) as i32) } @@ -245,8 +245,8 @@ impl Byte { return Err(jvm.exception("java/lang/ClassCastException", "not Byte").await); } let other = ClassInstanceRef::::from(other.instance); - let left: i8 = jvm.invoke_virtual(&this, "byteValue", "()B", ()).await?; - let right: i8 = jvm.invoke_virtual(&other, "byteValue", "()B", ()).await?; + let left: i8 = jvm.invoke_virtual(&this, "java/lang/Byte", "byteValue", "()B", ()).await?; + let right: i8 = jvm.invoke_virtual(&other, "java/lang/Byte", "byteValue", "()B", ()).await?; Ok(left.cmp(&right) as i32) } } diff --git a/java_runtime/src/classes/java/lang/character.rs b/java_runtime/src/classes/java/lang/character.rs index dea84a31..6b6e7113 100644 --- a/java_runtime/src/classes/java/lang/character.rs +++ b/java_runtime/src/classes/java/lang/character.rs @@ -396,12 +396,12 @@ impl Character { } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let value: JavaChar = jvm.invoke_virtual(&this, "charValue", "()C", ()).await?; + let value: JavaChar = jvm.invoke_virtual(&this, "java/lang/Character", "charValue", "()C", ()).await?; jvm.invoke_static("java/lang/String", "valueOf", "(C)Ljava/lang/String;", (value,)).await } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: JavaChar = jvm.invoke_virtual(&this, "charValue", "()C", ()).await?; + let value: JavaChar = jvm.invoke_virtual(&this, "java/lang/Character", "charValue", "()C", ()).await?; Ok(i32::from(value)) } @@ -410,8 +410,8 @@ impl Character { return Ok(false); } - let this_value: JavaChar = jvm.invoke_virtual(&this, "charValue", "()C", ()).await?; - let other_value: JavaChar = jvm.invoke_virtual(&other, "charValue", "()C", ()).await?; + let this_value: JavaChar = jvm.invoke_virtual(&this, "java/lang/Character", "charValue", "()C", ()).await?; + let other_value: JavaChar = jvm.invoke_virtual(&other, "java/lang/Character", "charValue", "()C", ()).await?; Ok(this_value == other_value) } @@ -423,8 +423,8 @@ impl Character { return Err(jvm.exception("java/lang/ClassCastException", "not Character").await); } - let this_value: JavaChar = jvm.invoke_virtual(&this, "charValue", "()C", ()).await?; - let other_value: JavaChar = jvm.invoke_virtual(&other, "charValue", "()C", ()).await?; + let this_value: JavaChar = jvm.invoke_virtual(&this, "java/lang/Character", "charValue", "()C", ()).await?; + let other_value: JavaChar = jvm.invoke_virtual(&other, "java/lang/Character", "charValue", "()C", ()).await?; Ok(this_value.cmp(&other_value) as i32) } @@ -437,8 +437,8 @@ impl Character { } let other = ClassInstanceRef::::from(other.instance); - let this_value: JavaChar = jvm.invoke_virtual(&this, "charValue", "()C", ()).await?; - let other_value: JavaChar = jvm.invoke_virtual(&other, "charValue", "()C", ()).await?; + let this_value: JavaChar = jvm.invoke_virtual(&this, "java/lang/Character", "charValue", "()C", ()).await?; + let other_value: JavaChar = jvm.invoke_virtual(&other, "java/lang/Character", "charValue", "()C", ()).await?; Ok(this_value.cmp(&other_value) as i32) } diff --git a/java_runtime/src/classes/java/lang/class.rs b/java_runtime/src/classes/java/lang/class.rs index 2891c88d..1097757e 100644 --- a/java_runtime/src/classes/java/lang/class.rs +++ b/java_runtime/src/classes/java/lang/class.rs @@ -252,8 +252,14 @@ impl Class { } let component_name = JavaLangString::from_rust_string(jvm, component_name).await?; - jvm.invoke_virtual(&defining_loader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", (component_name,)) - .await + jvm.invoke_virtual( + &defining_loader, + "java/lang/ClassLoader", + "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (component_name,), + ) + .await } async fn get_interfaces(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result>> { @@ -295,8 +301,14 @@ impl Class { class_loader.into() }; - jvm.invoke_virtual(&class_loader, "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;", (name,)) - .await + jvm.invoke_virtual( + &class_loader, + "java/lang/ClassLoader", + "getResourceAsStream", + "(Ljava/lang/String;)Ljava/io/InputStream;", + (name,), + ) + .await } async fn for_name(jvm: &Jvm, _context: &mut RuntimeContext, name: ClassInstanceRef) -> Result> { diff --git a/java_runtime/src/classes/java/lang/class_loader.rs b/java_runtime/src/classes/java/lang/class_loader.rs index 1ac583ca..0345b6bd 100644 --- a/java_runtime/src/classes/java/lang/class_loader.rs +++ b/java_runtime/src/classes/java/lang/class_loader.rs @@ -22,44 +22,54 @@ impl ClassLoader { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/lang/ClassLoader;)V", Self::init, Default::default()), - JavaMethodProto::new("loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", Self::load_class, Default::default()), - JavaMethodProto::new("findClass", "(Ljava/lang/String;)Ljava/lang/Class;", Self::find_class, Default::default()), + JavaMethodProto::new("", "(Ljava/lang/ClassLoader;)V", Self::init, MethodAccessFlags::PROTECTED), + JavaMethodProto::new( + "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + Self::load_class, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new( + "findClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + Self::find_class, + MethodAccessFlags::PROTECTED, + ), JavaMethodProto::new( "findLoadedClass", "(Ljava/lang/String;)Ljava/lang/Class;", Self::find_loaded_class, - Default::default(), + MethodAccessFlags::PROTECTED | MethodAccessFlags::FINAL, ), JavaMethodProto::new( "getSystemClassLoader", "()Ljava/lang/ClassLoader;", Self::get_system_class_loader, - MethodAccessFlags::STATIC, + MethodAccessFlags::PUBLIC | MethodAccessFlags::STATIC, ), JavaMethodProto::new( "getResource", "(Ljava/lang/String;)Ljava/net/URL;", Self::get_resource, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;", Self::get_resource_as_stream, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "findResource", "(Ljava/lang/String;)Ljava/net/URL;", Self::find_resource, - Default::default(), + MethodAccessFlags::PROTECTED, ), JavaMethodProto::new( "defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;", Self::define_class, - Default::default(), + MethodAccessFlags::PROTECTED | MethodAccessFlags::FINAL, ), ], fields: vec![ @@ -178,7 +188,13 @@ impl ClassLoader { tracing::debug!("java.lang.ClassLoader::loadClass({this:?}, {name:?})"); let class: ClassInstanceRef = jvm - .invoke_virtual(&this, "findLoadedClass", "(Ljava/lang/String;)Ljava/lang/Class;", (name.clone(),)) + .invoke_virtual( + &this, + "java/lang/ClassLoader", + "findLoadedClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (name.clone(),), + ) .await?; if !class.is_null() { @@ -193,7 +209,13 @@ impl ClassLoader { let defining_loader = if let Some(element_class_name) = ultimate_element_type.strip_prefix('L').and_then(|name| name.strip_suffix(';')) { let element_class_name = JavaLangString::from_rust_string(jvm, element_class_name).await?; let element_class: ClassInstanceRef = jvm - .invoke_virtual(&this, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", (element_class_name,)) + .invoke_virtual( + &this, + "java/lang/ClassLoader", + "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (element_class_name,), + ) .await?; jvm.get_field(&element_class, "classLoader", "Ljava/lang/ClassLoader;").await? } else { @@ -208,8 +230,14 @@ impl ClassLoader { let parent: ClassInstanceRef = jvm.get_field(&this, "parent", "Ljava/lang/ClassLoader;").await?; let class: ClassInstanceRef = if !parent.is_null() { - jvm.invoke_virtual(&parent, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", (name.clone(),)) - .await? + jvm.invoke_virtual( + &parent, + "java/lang/ClassLoader", + "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (name.clone(),), + ) + .await? } else { jvm.load_bootstrap_class(&internal_name).await?.into() }; @@ -219,7 +247,13 @@ impl ClassLoader { } let class = jvm - .invoke_virtual(&this, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;", (name,)) + .invoke_virtual( + &this, + "java/lang/ClassLoader", + "findClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (name,), + ) .await?; Ok(class) @@ -265,8 +299,14 @@ impl ClassLoader { let parent: ClassInstanceRef = jvm.get_field(&this, "parent", "Ljava/lang/ClassLoader;").await?; let result: ClassInstanceRef = if !parent.is_null() { - jvm.invoke_virtual(&parent, "getResource", "(Ljava/lang/String;)Ljava/net/URL;", (name.clone(),)) - .await? + jvm.invoke_virtual( + &parent, + "java/lang/ClassLoader", + "getResource", + "(Ljava/lang/String;)Ljava/net/URL;", + (name.clone(),), + ) + .await? } else { None.into() }; @@ -276,7 +316,13 @@ impl ClassLoader { } let result = jvm - .invoke_virtual(&this, "findResource", "(Ljava/lang/String;)Ljava/net/URL;", (name,)) + .invoke_virtual( + &this, + "java/lang/ClassLoader", + "findResource", + "(Ljava/lang/String;)Ljava/net/URL;", + (name,), + ) .await?; Ok(result) @@ -291,14 +337,22 @@ impl ClassLoader { tracing::debug!("java.lang.ClassLoader::getResourceAsStream({this:?})"); let resource_url: ClassInstanceRef = jvm - .invoke_virtual(&this, "getResource", "(Ljava/lang/String;)Ljava/net/URL;", (name.clone(),)) + .invoke_virtual( + &this, + "java/lang/ClassLoader", + "getResource", + "(Ljava/lang/String;)Ljava/net/URL;", + (name.clone(),), + ) .await?; if resource_url.is_null() { return Ok(None.into()); } - let stream = jvm.invoke_virtual(&resource_url, "openStream", "()Ljava/io/InputStream;", ()).await?; + let stream = jvm + .invoke_virtual(&resource_url, "java/net/URL", "openStream", "()Ljava/io/InputStream;", ()) + .await?; Ok(stream) } diff --git a/java_runtime/src/classes/java/lang/double.rs b/java_runtime/src/classes/java/lang/double.rs index e49b7e48..106051f3 100644 --- a/java_runtime/src/classes/java/lang/double.rs +++ b/java_runtime/src/classes/java/lang/double.rs @@ -232,27 +232,27 @@ impl Double { } async fn byte_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; Ok((value as i32) as i8) } async fn short_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; Ok((value as i32) as i16) } async fn int_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; Ok(value as i32) } async fn long_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; Ok(value as i64) } async fn float_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; Ok(value as f32) } @@ -298,7 +298,7 @@ impl Double { } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let value: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; Ok(JavaLangString::from_rust_string(jvm, &Self::format_value(value)).await?.into()) } @@ -307,7 +307,7 @@ impl Double { } async fn is_nan(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; Ok(value.is_nan()) } @@ -316,7 +316,7 @@ impl Double { } async fn is_infinite(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; Ok(value.is_infinite()) } @@ -333,7 +333,7 @@ impl Double { } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; let bits = if value.is_nan() { 0x7ff8_0000_0000_0000 } else { value.to_bits() }; Ok((bits ^ (bits >> 32)) as i32) } @@ -342,8 +342,8 @@ impl Double { if other.is_null() || !jvm.is_instance(&**other, "java/lang/Double") { return Ok(false); } - let left: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; - let right: f64 = jvm.invoke_virtual(&other, "doubleValue", "()D", ()).await?; + let left: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; + let right: f64 = jvm.invoke_virtual(&other, "java/lang/Double", "doubleValue", "()D", ()).await?; let left_bits = if left.is_nan() { 0x7ff8_0000_0000_0000 } else { left.to_bits() as i64 }; let right_bits = if right.is_nan() { 0x7ff8_0000_0000_0000 } else { right.to_bits() as i64 }; Ok(left_bits == right_bits) @@ -353,8 +353,8 @@ impl Double { if other.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "other").await); } - let left: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; - let right: f64 = jvm.invoke_virtual(&other, "doubleValue", "()D", ()).await?; + let left: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; + let right: f64 = jvm.invoke_virtual(&other, "java/lang/Double", "doubleValue", "()D", ()).await?; if left < right { return Ok(-1); } @@ -374,8 +374,8 @@ impl Double { return Err(jvm.exception("java/lang/ClassCastException", "not Double").await); } let other = ClassInstanceRef::::from(other.instance); - let left: f64 = jvm.invoke_virtual(&this, "doubleValue", "()D", ()).await?; - let right: f64 = jvm.invoke_virtual(&other, "doubleValue", "()D", ()).await?; + let left: f64 = jvm.invoke_virtual(&this, "java/lang/Double", "doubleValue", "()D", ()).await?; + let right: f64 = jvm.invoke_virtual(&other, "java/lang/Double", "doubleValue", "()D", ()).await?; if left < right { return Ok(-1); } diff --git a/java_runtime/src/classes/java/lang/enum.rs b/java_runtime/src/classes/java/lang/enum.rs index 17905f95..36963e2d 100644 --- a/java_runtime/src/classes/java/lang/enum.rs +++ b/java_runtime/src/classes/java/lang/enum.rs @@ -131,7 +131,8 @@ impl Enum { } async fn compare_to_object(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, other: ClassInstanceRef) -> Result { - jvm.invoke_virtual(&this, "compareTo", "(Ljava/lang/Enum;)I", (other,)).await + jvm.invoke_virtual(&this, "java/lang/Enum", "compareTo", "(Ljava/lang/Enum;)I", (other,)) + .await } async fn get_declaring_class(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { diff --git a/java_runtime/src/classes/java/lang/float.rs b/java_runtime/src/classes/java/lang/float.rs index ebe76242..abe7b54c 100644 --- a/java_runtime/src/classes/java/lang/float.rs +++ b/java_runtime/src/classes/java/lang/float.rs @@ -238,22 +238,22 @@ impl Float { } async fn byte_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; + let value: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; Ok((value as i32) as i8) } async fn short_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; + let value: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; Ok((value as i32) as i16) } async fn int_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; + let value: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; Ok(value as i32) } async fn long_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; + let value: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; Ok(value as i64) } @@ -262,7 +262,7 @@ impl Float { } async fn double_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; + let value: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; Ok(value as f64) } @@ -304,7 +304,7 @@ impl Float { } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let value: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; + let value: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; Ok(JavaLangString::from_rust_string(jvm, &Self::format_value(value)).await?.into()) } @@ -313,7 +313,7 @@ impl Float { } async fn is_nan(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; + let value: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; Ok(value.is_nan()) } @@ -322,7 +322,7 @@ impl Float { } async fn is_infinite(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; + let value: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; Ok(value.is_infinite()) } @@ -339,7 +339,7 @@ impl Float { } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; + let value: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; Ok(if value.is_nan() { 0x7fc0_0000 } else { value.to_bits() as i32 }) } @@ -347,8 +347,8 @@ impl Float { if other.is_null() || !jvm.is_instance(&**other, "java/lang/Float") { return Ok(false); } - let left: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; - let right: f32 = jvm.invoke_virtual(&other, "floatValue", "()F", ()).await?; + let left: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; + let right: f32 = jvm.invoke_virtual(&other, "java/lang/Float", "floatValue", "()F", ()).await?; let left_bits = if left.is_nan() { 0x7fc0_0000 } else { left.to_bits() as i32 }; let right_bits = if right.is_nan() { 0x7fc0_0000 } else { right.to_bits() as i32 }; Ok(left_bits == right_bits) @@ -358,8 +358,8 @@ impl Float { if other.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "other").await); } - let left: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; - let right: f32 = jvm.invoke_virtual(&other, "floatValue", "()F", ()).await?; + let left: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; + let right: f32 = jvm.invoke_virtual(&other, "java/lang/Float", "floatValue", "()F", ()).await?; if left < right { return Ok(-1); } @@ -379,8 +379,8 @@ impl Float { return Err(jvm.exception("java/lang/ClassCastException", "not Float").await); } let other = ClassInstanceRef::::from(other.instance); - let left: f32 = jvm.invoke_virtual(&this, "floatValue", "()F", ()).await?; - let right: f32 = jvm.invoke_virtual(&other, "floatValue", "()F", ()).await?; + let left: f32 = jvm.invoke_virtual(&this, "java/lang/Float", "floatValue", "()F", ()).await?; + let right: f32 = jvm.invoke_virtual(&other, "java/lang/Float", "floatValue", "()F", ()).await?; if left < right { return Ok(-1); } diff --git a/java_runtime/src/classes/java/lang/integer.rs b/java_runtime/src/classes/java/lang/integer.rs index c03ff503..04c490e4 100644 --- a/java_runtime/src/classes/java/lang/integer.rs +++ b/java_runtime/src/classes/java/lang/integer.rs @@ -341,17 +341,17 @@ impl Integer { } async fn long_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i32 = jvm.invoke_virtual(&this, "intValue", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&this, "java/lang/Integer", "intValue", "()I", ()).await?; Ok(value as i64) } async fn float_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i32 = jvm.invoke_virtual(&this, "intValue", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&this, "java/lang/Integer", "intValue", "()I", ()).await?; Ok(value as f32) } async fn double_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i32 = jvm.invoke_virtual(&this, "intValue", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&this, "java/lang/Integer", "intValue", "()I", ()).await?; Ok(value as f64) } @@ -375,7 +375,7 @@ impl Integer { } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let value: i32 = jvm.invoke_virtual(&this, "intValue", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&this, "java/lang/Integer", "intValue", "()I", ()).await?; Ok(JavaLangString::from_rust_string(jvm, &Self::format_value(value as i64, 10)).await?.into()) } @@ -424,8 +424,8 @@ impl Integer { if other.is_null() || !jvm.is_instance(&**other, "java/lang/Integer") { return Ok(false); } - let this_value: i32 = jvm.invoke_virtual(&this, "intValue", "()I", ()).await?; - let other_value: i32 = jvm.invoke_virtual(&other, "intValue", "()I", ()).await?; + let this_value: i32 = jvm.invoke_virtual(&this, "java/lang/Integer", "intValue", "()I", ()).await?; + let other_value: i32 = jvm.invoke_virtual(&other, "java/lang/Integer", "intValue", "()I", ()).await?; Ok(this_value == other_value) } @@ -433,8 +433,8 @@ impl Integer { if other.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "other").await); } - let this_value: i32 = jvm.invoke_virtual(&this, "intValue", "()I", ()).await?; - let other_value: i32 = jvm.invoke_virtual(&other, "intValue", "()I", ()).await?; + let this_value: i32 = jvm.invoke_virtual(&this, "java/lang/Integer", "intValue", "()I", ()).await?; + let other_value: i32 = jvm.invoke_virtual(&other, "java/lang/Integer", "intValue", "()I", ()).await?; Ok(this_value.cmp(&other_value) as i32) } @@ -446,8 +446,8 @@ impl Integer { return Err(jvm.exception("java/lang/ClassCastException", "java/lang/Object is not Integer").await); } let other = ClassInstanceRef::::from(other.instance); - let this_value: i32 = jvm.invoke_virtual(&this, "intValue", "()I", ()).await?; - let other_value: i32 = jvm.invoke_virtual(&other, "intValue", "()I", ()).await?; + let this_value: i32 = jvm.invoke_virtual(&this, "java/lang/Integer", "intValue", "()I", ()).await?; + let other_value: i32 = jvm.invoke_virtual(&other, "java/lang/Integer", "intValue", "()I", ()).await?; Ok(this_value.cmp(&other_value) as i32) } } diff --git a/java_runtime/src/classes/java/lang/long.rs b/java_runtime/src/classes/java/lang/long.rs index 0f27c139..669eadd1 100644 --- a/java_runtime/src/classes/java/lang/long.rs +++ b/java_runtime/src/classes/java/lang/long.rs @@ -352,7 +352,7 @@ impl Long { result.chars().rev().collect() } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let value: i64 = jvm.invoke_virtual(&this, "longValue", "()J", ()).await?; + let value: i64 = jvm.invoke_virtual(&this, "java/lang/Long", "longValue", "()J", ()).await?; Ok(JavaLangString::from_rust_string(jvm, &Self::format_value(value, 10)).await?.into()) } async fn to_string_static(jvm: &Jvm, _: &mut RuntimeContext, value: i64) -> Result> { @@ -388,24 +388,22 @@ impl Long { Ok(JavaLangString::from_rust_string(jvm, &text).await?.into()) } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i64 = jvm.invoke_virtual(&this, "longValue", "()J", ()).await?; + let value: i64 = jvm.invoke_virtual(&this, "java/lang/Long", "longValue", "()J", ()).await?; Ok((value ^ (value >> 32)) as i32) } async fn equals(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, other: ClassInstanceRef) -> Result { if other.is_null() || !jvm.is_instance(&**other, "java/lang/Long") { return Ok(false); } - Ok( - jvm.invoke_virtual::<_, i64>(&this, "longValue", "()J", ()).await? - == jvm.invoke_virtual::<_, i64>(&other, "longValue", "()J", ()).await?, - ) + Ok(jvm.invoke_virtual::<_, i64>(&this, "java/lang/Long", "longValue", "()J", ()).await? + == jvm.invoke_virtual::<_, i64>(&other, "java/lang/Long", "longValue", "()J", ()).await?) } async fn compare_to(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, other: ClassInstanceRef) -> Result { if other.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "other").await); } - let left: i64 = jvm.invoke_virtual(&this, "longValue", "()J", ()).await?; - let right: i64 = jvm.invoke_virtual(&other, "longValue", "()J", ()).await?; + let left: i64 = jvm.invoke_virtual(&this, "java/lang/Long", "longValue", "()J", ()).await?; + let right: i64 = jvm.invoke_virtual(&other, "java/lang/Long", "longValue", "()J", ()).await?; Ok(left.cmp(&right) as i32) } async fn compare_to_object(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, other: ClassInstanceRef) -> Result { @@ -416,8 +414,8 @@ impl Long { return Err(jvm.exception("java/lang/ClassCastException", "not Long").await); } let other = ClassInstanceRef::::from(other.instance); - let left: i64 = jvm.invoke_virtual(&this, "longValue", "()J", ()).await?; - let right: i64 = jvm.invoke_virtual(&other, "longValue", "()J", ()).await?; + let left: i64 = jvm.invoke_virtual(&this, "java/lang/Long", "longValue", "()J", ()).await?; + let right: i64 = jvm.invoke_virtual(&other, "java/lang/Long", "longValue", "()J", ()).await?; Ok(left.cmp(&right) as i32) } } diff --git a/java_runtime/src/classes/java/lang/math.rs b/java_runtime/src/classes/java/lang/math.rs index c9031925..21831c2e 100644 --- a/java_runtime/src/classes/java/lang/math.rs +++ b/java_runtime/src/classes/java/lang/math.rs @@ -324,6 +324,6 @@ impl Math { jvm.put_static_field("java/lang/Math", "randomNumberGenerator", "Ljava/util/Random;", random.clone()) .await?; } - jvm.invoke_virtual(&random, "nextDouble", "()D", ()).await + jvm.invoke_virtual(&random, "java/util/Random", "nextDouble", "()D", ()).await } } diff --git a/java_runtime/src/classes/java/lang/number.rs b/java_runtime/src/classes/java/lang/number.rs index 28229567..32859eb8 100644 --- a/java_runtime/src/classes/java/lang/number.rs +++ b/java_runtime/src/classes/java/lang/number.rs @@ -34,12 +34,12 @@ impl Number { } async fn byte_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i32 = jvm.invoke_virtual(&this, "intValue", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&this, "java/lang/Number", "intValue", "()I", ()).await?; Ok(value as i8) } async fn short_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let value: i32 = jvm.invoke_virtual(&this, "intValue", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&this, "java/lang/Number", "intValue", "()I", ()).await?; Ok(value as i16) } } diff --git a/java_runtime/src/classes/java/lang/object.rs b/java_runtime/src/classes/java/lang/object.rs index a64a1ebd..4fe013ce 100644 --- a/java_runtime/src/classes/java/lang/object.rs +++ b/java_runtime/src/classes/java/lang/object.rs @@ -49,18 +49,28 @@ impl Object { parent_class: None, interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("getClass", "()Ljava/lang/Class;", Self::get_class, Default::default()), - JavaMethodProto::new("hashCode", "()I", Self::hash_code, Default::default()), - JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, Default::default()), - JavaMethodProto::new("clone", "()Ljava/lang/Object;", Self::clone, MethodAccessFlags::NATIVE), - JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, Default::default()), - JavaMethodProto::new("notify", "()V", Self::notify, Default::default()), - JavaMethodProto::new("notifyAll", "()V", Self::notify_all, Default::default()), - JavaMethodProto::new("wait", "(J)V", Self::wait_long, Default::default()), - JavaMethodProto::new("wait", "(JI)V", Self::wait_long_int, Default::default()), - JavaMethodProto::new("wait", "()V", Self::wait, Default::default()), - JavaMethodProto::new("finalize", "()V", Self::finalize, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "getClass", + "()Ljava/lang/Class;", + Self::get_class, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "clone", + "()Ljava/lang/Object;", + Self::clone, + MethodAccessFlags::PROTECTED | MethodAccessFlags::NATIVE, + ), + JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("notify", "()V", Self::notify, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("notifyAll", "()V", Self::notify_all, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("wait", "(J)V", Self::wait_long, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("wait", "(JI)V", Self::wait_long_int, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("wait", "()V", Self::wait, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("finalize", "()V", Self::finalize, MethodAccessFlags::PROTECTED), ], fields: vec![], access_flags: Default::default(), @@ -117,11 +127,15 @@ impl Object { async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.lang.Object::toString({this:?})"); - let class = jvm.invoke_virtual(&this, "getClass", "()Ljava/lang/Class;", ()).await?; - let class_name = jvm.invoke_virtual(&class, "getName", "()Ljava/lang/String;", ()).await?; + let class = jvm + .invoke_virtual(&this, "java/lang/Object", "getClass", "()Ljava/lang/Class;", ()) + .await?; + let class_name = jvm + .invoke_virtual(&class, "java/lang/Class", "getName", "()Ljava/lang/String;", ()) + .await?; let class_name_rust = JavaLangString::to_rust_string(jvm, &class_name).await?; - let hash_code: i32 = jvm.invoke_virtual(&this, "hashCode", "()I", ()).await?; + let hash_code: i32 = jvm.invoke_virtual(&this, "java/lang/Object", "hashCode", "()I", ()).await?; let result = format!("{class_name_rust}@{hash_code:x}"); @@ -147,7 +161,7 @@ impl Object { async fn wait_long(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, millis: i64) -> Result<()> { tracing::debug!("java.lang.Object::wait({this:?}, {millis:?})"); - let _: () = jvm.invoke_virtual(&this, "wait", "(JI)V", (millis, 0)).await?; + let _: () = jvm.invoke_virtual(&this, "java/lang/Object", "wait", "(JI)V", (millis, 0)).await?; Ok(()) } @@ -195,7 +209,7 @@ impl Object { async fn wait(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { tracing::debug!("java.lang.Object::wait({this:?})"); - let _: () = jvm.invoke_virtual(&this, "wait", "(JI)V", (0i64, 0)).await?; + let _: () = jvm.invoke_virtual(&this, "java/lang/Object", "wait", "(JI)V", (0i64, 0)).await?; Ok(()) } diff --git a/java_runtime/src/classes/java/lang/short.rs b/java_runtime/src/classes/java/lang/short.rs index a913b7ec..e4feae81 100644 --- a/java_runtime/src/classes/java/lang/short.rs +++ b/java_runtime/src/classes/java/lang/short.rs @@ -169,7 +169,7 @@ impl Short { let integer = jvm .invoke_static("java/lang/Integer", "decode", "(Ljava/lang/String;)Ljava/lang/Integer;", (value,)) .await?; - let value: i32 = jvm.invoke_virtual(&integer, "intValue", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&integer, "java/lang/Integer", "intValue", "()I", ()).await?; if !(i32::from(i16::MIN)..=i32::from(i16::MAX)).contains(&value) { return Err(jvm.exception("java/lang/NumberFormatException", "Value out of range").await); } @@ -196,7 +196,7 @@ impl Short { } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let value: i16 = jvm.invoke_virtual(&this, "shortValue", "()S", ()).await?; + let value: i16 = jvm.invoke_virtual(&this, "java/lang/Short", "shortValue", "()S", ()).await?; Ok(JavaLangString::from_rust_string(jvm, &format!("{value}")).await?.into()) } async fn to_string_static(jvm: &Jvm, _: &mut RuntimeContext, value: i16) -> Result> { @@ -209,15 +209,15 @@ impl Short { if other.is_null() || !jvm.is_instance(&**other, "java/lang/Short") { return Ok(false); } - Ok(jvm.invoke_virtual::<_, i16>(&this, "shortValue", "()S", ()).await? - == jvm.invoke_virtual::<_, i16>(&other, "shortValue", "()S", ()).await?) + Ok(jvm.invoke_virtual::<_, i16>(&this, "java/lang/Short", "shortValue", "()S", ()).await? + == jvm.invoke_virtual::<_, i16>(&other, "java/lang/Short", "shortValue", "()S", ()).await?) } async fn compare_to(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, other: ClassInstanceRef) -> Result { if other.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "other").await); } - let left: i16 = jvm.invoke_virtual(&this, "shortValue", "()S", ()).await?; - let right: i16 = jvm.invoke_virtual(&other, "shortValue", "()S", ()).await?; + let left: i16 = jvm.invoke_virtual(&this, "java/lang/Short", "shortValue", "()S", ()).await?; + let right: i16 = jvm.invoke_virtual(&other, "java/lang/Short", "shortValue", "()S", ()).await?; Ok(left.cmp(&right) as i32) } async fn compare_to_object(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, other: ClassInstanceRef) -> Result { @@ -228,8 +228,8 @@ impl Short { return Err(jvm.exception("java/lang/ClassCastException", "not Short").await); } let other = ClassInstanceRef::::from(other.instance); - let left: i16 = jvm.invoke_virtual(&this, "shortValue", "()S", ()).await?; - let right: i16 = jvm.invoke_virtual(&other, "shortValue", "()S", ()).await?; + let left: i16 = jvm.invoke_virtual(&this, "java/lang/Short", "shortValue", "()S", ()).await?; + let right: i16 = jvm.invoke_virtual(&other, "java/lang/Short", "shortValue", "()S", ()).await?; Ok(left.cmp(&right) as i32) } } diff --git a/java_runtime/src/classes/java/lang/string.rs b/java_runtime/src/classes/java/lang/string.rs index f9650d68..38f18a1b 100644 --- a/java_runtime/src/classes/java/lang/string.rs +++ b/java_runtime/src/classes/java/lang/string.rs @@ -383,7 +383,9 @@ impl String { ) -> Result<()> { tracing::debug!("java.lang.String::({this:?}, {value:?})"); - let string: ClassInstanceRef = jvm.invoke_virtual(&value, "toString", "()Ljava/lang/String;", ()).await?; + let string: ClassInstanceRef = jvm + .invoke_virtual(&value, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; let _: () = jvm .invoke_special(&this, "java/lang/String", "", "(Ljava/lang/String;)V", (string,)) @@ -653,7 +655,7 @@ impl String { ) -> Result> { tracing::debug!("java.lang.String::subSequence({this:?}, {begin_index}, {end_index})"); - jvm.invoke_virtual(&this, "substring", "(II)Ljava/lang/String;", (begin_index, end_index)) + jvm.invoke_virtual(&this, "java/lang/String", "substring", "(II)Ljava/lang/String;", (begin_index, end_index)) .await } @@ -681,14 +683,15 @@ impl String { Ok(if value.is_null() { JavaLangString::from_rust_string(jvm, "null").await?.into() } else { - jvm.invoke_virtual(&value, "toString", "()Ljava/lang/String;", ()).await? + jvm.invoke_virtual(&value, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await? }) } async fn index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, ch: i32) -> Result { tracing::debug!("java.lang.String::indexOf({this:?}, {ch:?})"); - jvm.invoke_virtual(&this, "indexOf", "(II)I", (ch, 0)).await + jvm.invoke_virtual(&this, "java/lang/String", "indexOf", "(II)I", (ch, 0)).await } async fn index_of_from(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, ch: i32, from_index: i32) -> Result { @@ -711,7 +714,8 @@ impl String { async fn index_of_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, str: ClassInstanceRef) -> Result { tracing::debug!("java.lang.String::indexOf({this:?}, {str:?})"); - jvm.invoke_virtual(&this, "indexOf", "(Ljava/lang/String;I)I", (str, 0)).await + jvm.invoke_virtual(&this, "java/lang/String", "indexOf", "(Ljava/lang/String;I)I", (str, 0)) + .await } async fn index_of_string_from( @@ -795,13 +799,15 @@ impl String { return Err(jvm.exception("java/lang/NullPointerException", "locale is null").await); } - jvm.invoke_virtual(&this, "toUpperCase", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&this, "java/lang/String", "toUpperCase", "()Ljava/lang/String;", ()) + .await } async fn starts_with(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, prefix: ClassInstanceRef) -> Result { tracing::debug!("java.lang.String::startsWith({this:?}, {prefix:?})"); - jvm.invoke_virtual(&this, "startsWith", "(Ljava/lang/String;I)Z", (prefix, 0)).await + jvm.invoke_virtual(&this, "java/lang/String", "startsWith", "(Ljava/lang/String;I)Z", (prefix, 0)) + .await } async fn starts_with_offset( @@ -958,7 +964,8 @@ impl String { return Err(jvm.exception("java/lang/NullPointerException", "locale is null").await); } - jvm.invoke_virtual(&this, "toLowerCase", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&this, "java/lang/String", "toLowerCase", "()Ljava/lang/String;", ()) + .await } async fn replace( @@ -1015,10 +1022,22 @@ impl String { .await?; let input: ClassInstanceRef = ClassInstanceRef::new(this.instance); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - jvm.invoke_virtual(&matcher, "replaceFirst", "(Ljava/lang/String;)Ljava/lang/String;", (replacement,)) - .await + jvm.invoke_virtual( + &matcher, + "java/util/regex/Matcher", + "replaceFirst", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement,), + ) + .await } async fn replace_all( @@ -1040,10 +1059,22 @@ impl String { .await?; let input: ClassInstanceRef = ClassInstanceRef::new(this.instance); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - jvm.invoke_virtual(&matcher, "replaceAll", "(Ljava/lang/String;)Ljava/lang/String;", (replacement,)) - .await + jvm.invoke_virtual( + &matcher, + "java/util/regex/Matcher", + "replaceAll", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement,), + ) + .await } async fn split( @@ -1063,8 +1094,14 @@ impl String { ) .await?; let input: ClassInstanceRef = ClassInstanceRef::new(this.instance); - jvm.invoke_virtual(&pattern, "split", "(Ljava/lang/CharSequence;)[Ljava/lang/String;", (input,)) - .await + jvm.invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;)[Ljava/lang/String;", + (input,), + ) + .await } async fn split_with_limit( @@ -1085,8 +1122,14 @@ impl String { ) .await?; let input: ClassInstanceRef = ClassInstanceRef::new(this.instance); - jvm.invoke_virtual(&pattern, "split", "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", (input, limit)) - .await + jvm.invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", + (input, limit), + ) + .await } async fn format( @@ -1099,12 +1142,14 @@ impl String { let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + "java/util/Formatter", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&formatter, "java/util/Formatter", "toString", "()Ljava/lang/String;", ()) + .await } async fn format_with_locale( @@ -1118,12 +1163,14 @@ impl String { let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + "java/util/Formatter", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&formatter, "java/util/Formatter", "toString", "()Ljava/lang/String;", ()) + .await } #[allow(clippy::too_many_arguments)] @@ -1184,8 +1231,14 @@ impl String { ) -> Result { tracing::debug!("java.lang.String::regionMatches({this:?}, {toffset}, {other:?}, {ooffset}, {len})"); - jvm.invoke_virtual(&this, "regionMatches", "(ZILjava/lang/String;II)Z", (false, toffset, other, ooffset, len)) - .await + jvm.invoke_virtual( + &this, + "java/lang/String", + "regionMatches", + "(ZILjava/lang/String;II)Z", + (false, toffset, other, ooffset, len), + ) + .await } async fn last_index_of_from(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, ch: i32, from_index: i32) -> Result { @@ -1211,7 +1264,8 @@ impl String { tracing::debug!("java.lang.String::lastIndexOf({this:?}, {str:?})"); let length: i32 = jvm.get_field(&this, "count", "I").await?; - jvm.invoke_virtual(&this, "lastIndexOf", "(Ljava/lang/String;I)I", (str, length)).await + jvm.invoke_virtual(&this, "java/lang/String", "lastIndexOf", "(Ljava/lang/String;I)I", (str, length)) + .await } async fn last_index_of_string_from( diff --git a/java_runtime/src/classes/java/lang/string_buffer.rs b/java_runtime/src/classes/java/lang/string_buffer.rs index 51c638b0..aeb5f322 100644 --- a/java_runtime/src/classes/java/lang/string_buffer.rs +++ b/java_runtime/src/classes/java/lang/string_buffer.rs @@ -517,7 +517,13 @@ impl StringBuffer { .invoke_special(&this, "java/lang/AbstractStringBuilder", "", "(I)V", ((chars.len() + 16) as i32,)) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (string,)) + .invoke_virtual( + &this, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (string,), + ) .await?; Ok(()) } @@ -531,12 +537,20 @@ impl StringBuffer { if sequence.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "seq is null").await); } - let length: i32 = jvm.invoke_virtual(&sequence, "length", "()I", ()).await?; + let length: i32 = jvm + .invoke_virtual(&sequence, &sequence.class_definition().name(), "length", "()I", ()) + .await?; let _: () = jvm .invoke_special(&this, "java/lang/AbstractStringBuilder", "", "(I)V", (length + 16,)) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&this, "append", "(Ljava/lang/CharSequence;)Ljava/lang/StringBuffer;", (sequence,)) + .invoke_virtual( + &this, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/CharSequence;)Ljava/lang/StringBuffer;", + (sequence,), + ) .await?; Ok(()) } @@ -569,10 +583,17 @@ impl StringBuffer { let string: ClassInstanceRef = if object.is_null() { JavaLangString::from_rust_string(jvm, "null").await?.into() } else { - jvm.invoke_virtual(&object, "toString", "()Ljava/lang/String;", ()).await? + jvm.invoke_virtual(&object, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await? }; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (string,), + ) + .await } async fn append_string_buffer( @@ -635,8 +656,14 @@ impl StringBuffer { tracing::debug!("java.lang.StringBuffer::append({this:?}, {value})"); let string = JavaLangString::from_rust_string(jvm, if value { "true" } else { "false" }).await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (string,), + ) + .await } async fn append_character( @@ -655,8 +682,14 @@ impl StringBuffer { tracing::debug!("java.lang.StringBuffer::append({this:?}, {value})"); let string = JavaLangString::from_rust_string(jvm, &value.to_string()).await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (string,), + ) + .await } async fn append_code_point(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, code_point: i32) -> Result> { @@ -676,8 +709,14 @@ impl StringBuffer { tracing::debug!("java.lang.StringBuffer::append({this:?}, {value})"); let string = JavaLangString::from_rust_string(jvm, &value.to_string()).await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (string,), + ) + .await } async fn append_float(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f32) -> Result> { @@ -686,8 +725,14 @@ impl StringBuffer { let string: ClassInstanceRef = jvm .invoke_static("java/lang/Float", "toString", "(F)Ljava/lang/String;", (value,)) .await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (string,), + ) + .await } async fn append_double(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: f64) -> Result> { @@ -696,8 +741,14 @@ impl StringBuffer { let string: ClassInstanceRef = jvm .invoke_static("java/lang/Double", "toString", "(D)Ljava/lang/String;", (value,)) .await?; - jvm.invoke_virtual(&this, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (string,)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (string,), + ) + .await } async fn append_char_array_all( @@ -774,10 +825,17 @@ impl StringBuffer { let string: ClassInstanceRef = if object.is_null() { JavaLangString::from_rust_string(jvm, "null").await?.into() } else { - jvm.invoke_virtual(&object, "toString", "()Ljava/lang/String;", ()).await? + jvm.invoke_virtual(&object, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await? }; - jvm.invoke_virtual(&this, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (offset, string)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (offset, string), + ) + .await } async fn insert_boolean( @@ -790,8 +848,14 @@ impl StringBuffer { tracing::debug!("java.lang.StringBuffer::insert({this:?}, {offset}, {value})"); let string = JavaLangString::from_rust_string(jvm, if value { "true" } else { "false" }).await?; - jvm.invoke_virtual(&this, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (offset, string)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (offset, string), + ) + .await } async fn insert_character( @@ -817,16 +881,28 @@ impl StringBuffer { tracing::debug!("java.lang.StringBuffer::insert({this:?}, {offset}, {value})"); let string = JavaLangString::from_rust_string(jvm, &value.to_string()).await?; - jvm.invoke_virtual(&this, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (offset, string)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (offset, string), + ) + .await } async fn insert_long(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, offset: i32, value: i64) -> Result> { tracing::debug!("java.lang.StringBuffer::insert({this:?}, {offset}, {value})"); let string = JavaLangString::from_rust_string(jvm, &value.to_string()).await?; - jvm.invoke_virtual(&this, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (offset, string)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (offset, string), + ) + .await } async fn insert_float( @@ -841,8 +917,14 @@ impl StringBuffer { let string: ClassInstanceRef = jvm .invoke_static("java/lang/Float", "toString", "(F)Ljava/lang/String;", (value,)) .await?; - jvm.invoke_virtual(&this, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (offset, string)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (offset, string), + ) + .await } async fn insert_double( @@ -857,8 +939,14 @@ impl StringBuffer { let string: ClassInstanceRef = jvm .invoke_static("java/lang/Double", "toString", "(D)Ljava/lang/String;", (value,)) .await?; - jvm.invoke_virtual(&this, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (offset, string)) - .await + jvm.invoke_virtual( + &this, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (offset, string), + ) + .await } async fn insert_char_array( @@ -918,18 +1006,33 @@ impl StringBuffer { if sequence.is_null() { let sequence = JavaLangString::from_rust_string(jvm, "null").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&this, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (offset, sequence)) + .invoke_virtual( + &this, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (offset, sequence), + ) .await?; } else if jvm.is_instance(&**sequence, "java/lang/String") { let sequence: ClassInstanceRef = ClassInstanceRef::new(sequence.instance); let _: ClassInstanceRef = jvm - .invoke_virtual(&this, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (offset, sequence)) + .invoke_virtual( + &this, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (offset, sequence), + ) .await?; } else { - let length: i32 = jvm.invoke_virtual(&sequence, "length", "()I", ()).await?; + let length: i32 = jvm + .invoke_virtual(&sequence, &sequence.class_definition().name(), "length", "()I", ()) + .await?; let _: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/lang/StringBuffer", "insert", "(ILjava/lang/CharSequence;II)Ljava/lang/StringBuffer;", (offset, sequence, 0, length), @@ -1044,7 +1147,8 @@ impl StringBuffer { tracing::debug!("java.lang.StringBuffer::substring({this:?}, {start})"); let count: i32 = jvm.get_field(&this, "count", "I").await?; - jvm.invoke_virtual(&this, "substring", "(II)Ljava/lang/String;", (start, count)).await + jvm.invoke_virtual(&this, "java/lang/StringBuffer", "substring", "(II)Ljava/lang/String;", (start, count)) + .await } async fn substring_range( @@ -1079,7 +1183,8 @@ impl StringBuffer { ) -> Result> { tracing::debug!("java.lang.StringBuffer::subSequence({this:?}, {start}, {end})"); - jvm.invoke_virtual(&this, "substring", "(II)Ljava/lang/String;", (start, end)).await + jvm.invoke_virtual(&this, "java/lang/StringBuffer", "substring", "(II)Ljava/lang/String;", (start, end)) + .await } async fn reverse(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { diff --git a/java_runtime/src/classes/java/lang/string_builder.rs b/java_runtime/src/classes/java/lang/string_builder.rs index 5d64a110..3cfaff67 100644 --- a/java_runtime/src/classes/java/lang/string_builder.rs +++ b/java_runtime/src/classes/java/lang/string_builder.rs @@ -397,7 +397,9 @@ impl StringBuilder { if sequence.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "seq is null").await); } - let length: i32 = jvm.invoke_virtual(&sequence, "length", "()I", ()).await?; + let length: i32 = jvm + .invoke_virtual(&sequence, &sequence.class_definition().name(), "length", "()I", ()) + .await?; let _: () = jvm .invoke_special(&this, "java/lang/AbstractStringBuilder", "", "(I)V", (length + 16,)) .await?; diff --git a/java_runtime/src/classes/java/lang/system.rs b/java_runtime/src/classes/java/lang/system.rs index f94667a8..1b9a51b4 100644 --- a/java_runtime/src/classes/java/lang/system.rs +++ b/java_runtime/src/classes/java/lang/system.rs @@ -191,7 +191,13 @@ impl System { let props = jvm.get_static_field("java/lang/System", "props", "Ljava/util/Properties;").await?; let value = jvm - .invoke_virtual(&props, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &props, + "java/util/Properties", + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; Ok(value) @@ -212,6 +218,7 @@ impl System { let props = jvm.get_static_field("java/lang/System", "props", "Ljava/util/Properties;").await?; jvm.invoke_virtual( &props, + "java/util/Properties", "getProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (key, default_value), @@ -265,6 +272,7 @@ impl System { let value = jvm .invoke_virtual( &props, + "java/util/Properties", "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;", (key, value), diff --git a/java_runtime/src/classes/java/lang/thread.rs b/java_runtime/src/classes/java/lang/thread.rs index 09877191..907b217e 100644 --- a/java_runtime/src/classes/java/lang/thread.rs +++ b/java_runtime/src/classes/java/lang/thread.rs @@ -268,7 +268,7 @@ impl Thread { self.jvm.attach_thread(self.this.instance.clone()).await?; - let result: Result<()> = self.jvm.invoke_virtual(&self.this, "run", "()V", []).await; + let result: Result<()> = self.jvm.invoke_virtual(&self.this, "java/lang/Thread", "run", "()V", []).await; if let Err(jvm::JavaError::JavaException(exception)) = &result { let trace = async { @@ -279,9 +279,18 @@ impl Thread { .await?; let _: () = self .jvm - .invoke_virtual(exception, "printStackTrace", "(Ljava/io/PrintWriter;)V", (print_writer,)) + .invoke_virtual( + exception, + &exception.class_definition().name(), + "printStackTrace", + "(Ljava/io/PrintWriter;)V", + (print_writer,), + ) + .await?; + let trace = self + .jvm + .invoke_virtual(&string_writer, "java/io/StringWriter", "toString", "()Ljava/lang/String;", []) .await?; - let trace = self.jvm.invoke_virtual(&string_writer, "toString", "()Ljava/lang/String;", []).await?; JavaLangString::to_rust_string(&self.jvm, &trace).await } .await; @@ -317,7 +326,7 @@ impl Thread { jvm.put_field(&mut this, "started", "Z", true).await?; jvm.put_field(&mut this, "alive", "Z", true).await?; - let id: i32 = jvm.invoke_virtual(&this, "hashCode", "()I", ()).await?; + let id: i32 = jvm.invoke_virtual(&this, "java/lang/Object", "hashCode", "()I", ()).await?; let this = match jvm.new_global_ref(&this) { Some(this) => this, @@ -340,7 +349,7 @@ impl Thread { let target: ClassInstanceRef = jvm.get_field(&this, "target", "Ljava/lang/Runnable;").await?; if !target.is_null() { - let _: () = jvm.invoke_virtual(&target, "run", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&target, &target.class_definition().name(), "run", "()V", ()).await?; } Ok(()) @@ -349,7 +358,7 @@ impl Thread { async fn join(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { tracing::debug!("java.lang.Thread::join({this:?})"); - let _: () = jvm.invoke_virtual(&this, "join", "(J)V", (0i64,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/lang/Thread", "join", "(J)V", (0i64,)).await?; Ok(()) } @@ -369,13 +378,15 @@ impl Thread { } if millis == 0 { - let _: () = jvm.invoke_virtual(&this, "wait", "(J)V", (0i64,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/lang/Object", "wait", "(J)V", (0i64,)).await?; } else { let elapsed = context.now().saturating_sub(start); if elapsed >= millis as u64 { return Ok(()); } - let _: () = jvm.invoke_virtual(&this, "wait", "(J)V", (millis - elapsed as i64,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/lang/Object", "wait", "(J)V", (millis - elapsed as i64,)) + .await?; } } } @@ -434,7 +445,9 @@ impl Thread { async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.lang.Thread::toString({this:?})"); - let name: ClassInstanceRef = jvm.invoke_virtual(&this, "getName", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/lang/Thread", "getName", "()Ljava/lang/String;", ()) + .await?; let name = JavaLangString::to_rust_string(jvm, &name).await?; let priority: i32 = jvm.get_field(&this, "priority", "I").await?; Ok(JavaLangString::from_rust_string(jvm, &format!("Thread[{name},{priority}]")).await?.into()) diff --git a/java_runtime/src/classes/java/lang/throwable.rs b/java_runtime/src/classes/java/lang/throwable.rs index 48e9cf79..d74ddbfb 100644 --- a/java_runtime/src/classes/java/lang/throwable.rs +++ b/java_runtime/src/classes/java/lang/throwable.rs @@ -1,7 +1,7 @@ use alloc::{boxed::Box, format, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstance, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -22,17 +22,22 @@ impl Throwable { parent_class: Some("java/lang/Object"), interfaces: vec!["java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/Throwable;)V", Self::init_with_cause, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/Throwable;)V", Self::init_with_cause, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/lang/String;Ljava/lang/Throwable;)V", Self::init_with_message_and_cause, - Default::default(), + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new( + "getCause", + "()Ljava/lang/Throwable;", + Self::get_cause, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), - JavaMethodProto::new("getCause", "()Ljava/lang/Throwable;", Self::get_cause, Default::default()), - JavaMethodProto::new("getMessage", "()Ljava/lang/String;", Self::get_message, Default::default()), + JavaMethodProto::new("getMessage", "()Ljava/lang/String;", Self::get_message, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "getLocalizedMessage", "()Ljava/lang/String;", @@ -43,27 +48,27 @@ impl Throwable { "initCause", "(Ljava/lang/Throwable;)Ljava/lang/Throwable;", Self::init_cause, - Default::default(), + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), - JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, Default::default()), + JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "fillInStackTrace", "()Ljava/lang/Throwable;", Self::fill_in_stack_trace, - Default::default(), + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), - JavaMethodProto::new("printStackTrace", "()V", Self::print_stack_trace, Default::default()), + JavaMethodProto::new("printStackTrace", "()V", Self::print_stack_trace, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "printStackTrace", "(Ljava/io/PrintStream;)V", Self::print_stack_trace_to_print_stream, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "printStackTrace", "(Ljava/io/PrintWriter;)V", Self::print_stack_trace_to_print_writer, - Default::default(), + MethodAccessFlags::PUBLIC, ), ], fields: vec![ @@ -71,7 +76,7 @@ impl Throwable { JavaFieldProto::new("cause", "Ljava/lang/Throwable;", Default::default()), JavaFieldProto::new("stackTrace", "[Ljava/lang/String;", Default::default()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -80,7 +85,9 @@ impl Throwable { let _: () = jvm.invoke_special(&this, "java/lang/Object", "", "()V", ()).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "fillInStackTrace", "()Ljava/lang/Throwable;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/lang/Throwable", "fillInStackTrace", "()Ljava/lang/Throwable;", ()) + .await?; Ok(()) } @@ -92,7 +99,9 @@ impl Throwable { jvm.put_field(&mut this, "detailMessage", "Ljava/lang/String;", message).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "fillInStackTrace", "()Ljava/lang/Throwable;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/lang/Throwable", "fillInStackTrace", "()Ljava/lang/Throwable;", ()) + .await?; Ok(()) } @@ -105,12 +114,15 @@ impl Throwable { let message: ClassInstanceRef = if cause.is_null() { None.into() } else { - jvm.invoke_virtual(&cause, "toString", "()Ljava/lang/String;", ()).await? + jvm.invoke_virtual(&cause, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await? }; jvm.put_field(&mut this, "detailMessage", "Ljava/lang/String;", message).await?; jvm.put_field(&mut this, "cause", "Ljava/lang/Throwable;", cause).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "fillInStackTrace", "()Ljava/lang/Throwable;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/lang/Throwable", "fillInStackTrace", "()Ljava/lang/Throwable;", ()) + .await?; Ok(()) } @@ -129,7 +141,9 @@ impl Throwable { jvm.put_field(&mut this, "detailMessage", "Ljava/lang/String;", message).await?; jvm.put_field(&mut this, "cause", "Ljava/lang/Throwable;", cause).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "fillInStackTrace", "()Ljava/lang/Throwable;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/lang/Throwable", "fillInStackTrace", "()Ljava/lang/Throwable;", ()) + .await?; Ok(()) } @@ -149,7 +163,8 @@ impl Throwable { async fn get_localized_message(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.lang.Throwable::getLocalizedMessage({this:?})"); - jvm.invoke_virtual(&this, "getMessage", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&this, "java/lang/Throwable", "getMessage", "()Ljava/lang/String;", ()) + .await } async fn init_cause( @@ -184,7 +199,9 @@ impl Throwable { let err: ClassInstanceRef = jvm.get_static_field("java/lang/System", "err", "Ljava/io/PrintStream;").await?; - let _: () = jvm.invoke_virtual(&this, "printStackTrace", "(Ljava/io/PrintStream;)V", (err,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/lang/Throwable", "printStackTrace", "(Ljava/io/PrintStream;)V", (err,)) + .await?; Ok(()) } @@ -218,8 +235,12 @@ impl Throwable { async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.lang.Throwable::toString({this:?})"); - let class = jvm.invoke_virtual(&this, "getClass", "()Ljava/lang/Class;", ()).await?; - let class_name = jvm.invoke_virtual(&class, "getName", "()Ljava/lang/String;", ()).await?; + let class = jvm + .invoke_virtual(&this, "java/lang/Object", "getClass", "()Ljava/lang/Class;", ()) + .await?; + let class_name = jvm + .invoke_virtual(&class, "java/lang/Class", "getName", "()Ljava/lang/String;", ()) + .await?; let message: ClassInstanceRef = jvm.get_field(&this, "detailMessage", "Ljava/lang/String;").await?; @@ -246,7 +267,9 @@ impl Throwable { // a malformed initCause could create a cycle, so cap the depth for _ in 0..32 { - let string: ClassInstanceRef = jvm.invoke_virtual(¤t, "toString", "()Ljava/lang/String;", ()).await?; + let string: ClassInstanceRef = jvm + .invoke_virtual(¤t, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; let prefix: ClassInstanceRef = match header { Some(x) => { let string = JavaLangString::to_rust_string(jvm, &string).await?; @@ -255,7 +278,13 @@ impl Throwable { None => string, }; let _: () = jvm - .invoke_virtual(&stream_or_writer, "println", "(Ljava/lang/String;)V", (prefix,)) + .invoke_virtual( + &stream_or_writer, + &stream_or_writer.class_definition().name(), + "println", + "(Ljava/lang/String;)V", + (prefix,), + ) .await?; let stack_trace: ClassInstanceRef>> = jvm.get_field(¤t, "stackTrace", "[Ljava/lang/String;").await?; @@ -266,11 +295,21 @@ impl Throwable { let line = JavaLangString::to_rust_string(jvm, &line_ref).await?; let line = format!("\tat {line}"); let line = JavaLangString::from_rust_string(jvm, &line).await?; - let _: () = jvm.invoke_virtual(&stream_or_writer, "println", "(Ljava/lang/String;)V", (line,)).await?; + let _: () = jvm + .invoke_virtual( + &stream_or_writer, + &stream_or_writer.class_definition().name(), + "println", + "(Ljava/lang/String;)V", + (line,), + ) + .await?; } } - let cause: ClassInstanceRef = jvm.invoke_virtual(¤t, "getCause", "()Ljava/lang/Throwable;", ()).await?; + let cause: ClassInstanceRef = jvm + .invoke_virtual(¤t, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;", ()) + .await?; if cause.is_null() { break; } diff --git a/java_runtime/src/classes/java/net/jar_url_connection.rs b/java_runtime/src/classes/java/net/jar_url_connection.rs index 7cfd6f9a..21971cb4 100644 --- a/java_runtime/src/classes/java/net/jar_url_connection.rs +++ b/java_runtime/src/classes/java/net/jar_url_connection.rs @@ -1,7 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -19,16 +19,21 @@ impl JarURLConnection { parent_class: Some("java/net/URLConnection"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/net/URL;)V", Self::init, Default::default()), - JavaMethodProto::new_abstract("getJarFile", "()Ljava/util/jar/JarFile;", Default::default()), - JavaMethodProto::new("getEntryName", "()Ljava/lang/String;", Self::get_entry_name, Default::default()), - JavaMethodProto::new("getJarFileURL", "()Ljava/net/URL;", Self::get_jar_file_url, Default::default()), - JavaMethodProto::new("getJarEntry", "()Ljava/util/jar/JarEntry;", Self::get_jar_entry, Default::default()), + JavaMethodProto::new("", "(Ljava/net/URL;)V", Self::init, MethodAccessFlags::PROTECTED), + JavaMethodProto::new_abstract("getJarFile", "()Ljava/util/jar/JarFile;", MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getEntryName", "()Ljava/lang/String;", Self::get_entry_name, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getJarFileURL", "()Ljava/net/URL;", Self::get_jar_file_url, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "getJarEntry", + "()Ljava/util/jar/JarEntry;", + Self::get_jar_entry, + MethodAccessFlags::PUBLIC, + ), JavaMethodProto::new( "getMainAttributes", "()Ljava/util/jar/Attributes;", Self::get_main_attributes, - Default::default(), + MethodAccessFlags::PUBLIC, ), ], fields: vec![ @@ -46,7 +51,7 @@ impl JarURLConnection { .invoke_special(&this, "java/net/URLConnection", "", "(Ljava/net/URL;)V", (url.clone(),)) .await?; - let file = jvm.invoke_virtual(&url, "getFile", "()Ljava/lang/String;", ()).await?; + let file = jvm.invoke_virtual(&url, "java/net/URL", "getFile", "()Ljava/lang/String;", ()).await?; let file = JavaLangString::to_rust_string(jvm, &file).await?; let split = file.splitn(2, "!/").collect::>(); @@ -79,11 +84,21 @@ impl JarURLConnection { async fn get_jar_entry(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.net.JarURLConnection::getJarEntry({this:?})"); - let jar_file = jvm.invoke_virtual(&this, "getJarFile", "()Ljava/util/jar/JarFile;", ()).await?; - let entry_name: ClassInstanceRef = jvm.invoke_virtual(&this, "getEntryName", "()Ljava/lang/String;", ()).await?; + let jar_file = jvm + .invoke_virtual(&this, "java/net/JarURLConnection", "getJarFile", "()Ljava/util/jar/JarFile;", ()) + .await?; + let entry_name: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/net/JarURLConnection", "getEntryName", "()Ljava/lang/String;", ()) + .await?; let entry = jvm - .invoke_virtual(&jar_file, "getJarEntry", "(Ljava/lang/String;)Ljava/util/jar/JarEntry;", (entry_name,)) + .invoke_virtual( + &jar_file, + "java/util/jar/JarFile", + "getJarEntry", + "(Ljava/lang/String;)Ljava/util/jar/JarEntry;", + (entry_name,), + ) .await?; Ok(entry) @@ -92,10 +107,20 @@ impl JarURLConnection { async fn get_main_attributes(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.net.JarURLConnection::getMainAttributes({this:?})"); - let jar_file = jvm.invoke_virtual(&this, "getJarFile", "()Ljava/util/jar/JarFile;", ()).await?; - let manifest = jvm.invoke_virtual(&jar_file, "getManifest", "()Ljava/util/jar/Manifest;", ()).await?; + let jar_file = jvm + .invoke_virtual(&this, "java/net/JarURLConnection", "getJarFile", "()Ljava/util/jar/JarFile;", ()) + .await?; + let manifest = jvm + .invoke_virtual(&jar_file, "java/util/jar/JarFile", "getManifest", "()Ljava/util/jar/Manifest;", ()) + .await?; let main_attributes = jvm - .invoke_virtual(&manifest, "getMainAttributes", "()Ljava/util/jar/Attributes;", ()) + .invoke_virtual( + &manifest, + "java/util/jar/Manifest", + "getMainAttributes", + "()Ljava/util/jar/Attributes;", + (), + ) .await?; Ok(main_attributes) diff --git a/java_runtime/src/classes/java/net/url.rs b/java_runtime/src/classes/java/net/url.rs index a21f1822..bfda6e65 100644 --- a/java_runtime/src/classes/java/net/url.rs +++ b/java_runtime/src/classes/java/net/url.rs @@ -127,6 +127,7 @@ impl URL { let _: () = jvm .invoke_virtual( &handler, + "java/net/URLStreamHandler", "parseURL", "(Ljava/net/URL;Ljava/lang/String;II)V", (this, spec, 0, spec_str.len() as i32), @@ -180,6 +181,7 @@ impl URL { let _: () = jvm .invoke_virtual( &this, + "java/net/URL", "set", "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V", (protocol.clone(), host, port, file, None), @@ -222,7 +224,13 @@ impl URL { let handler = jvm.get_field(&this, "handler", "Ljava/net/URLStreamHandler;").await?; let connection = jvm - .invoke_virtual(&handler, "openConnection", "(Ljava/net/URL;)Ljava/net/URLConnection;", (this,)) + .invoke_virtual( + &handler, + "java/net/URLStreamHandler", + "openConnection", + "(Ljava/net/URL;)Ljava/net/URLConnection;", + (this,), + ) .await?; Ok(connection) @@ -231,9 +239,13 @@ impl URL { async fn open_stream(jvm: &Jvm, _runtime: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.net.URL::openStream({this:?})"); - let connection = jvm.invoke_virtual(&this, "openConnection", "()Ljava/net/URLConnection;", ()).await?; + let connection = jvm + .invoke_virtual(&this, "java/net/URL", "openConnection", "()Ljava/net/URLConnection;", ()) + .await?; - let stream = jvm.invoke_virtual(&connection, "getInputStream", "()Ljava/io/InputStream;", ()).await?; + let stream = jvm + .invoke_virtual(&connection, "java/net/URLConnection", "getInputStream", "()Ljava/io/InputStream;", ()) + .await?; Ok(stream) } diff --git a/java_runtime/src/classes/java/net/url_class_loader.rs b/java_runtime/src/classes/java/net/url_class_loader.rs index a6822022..49b9c092 100644 --- a/java_runtime/src/classes/java/net/url_class_loader.rs +++ b/java_runtime/src/classes/java/net/url_class_loader.rs @@ -1,6 +1,7 @@ use alloc::{format, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::MethodAccessFlags; use jvm::{ Array, ClassInstanceRef, Jvm, Result, runtime::{JavaIoInputStream, JavaLangString}, @@ -25,13 +26,23 @@ impl URLClassLoader { parent_class: Some("java/lang/ClassLoader"), // TODO java.security.SecureClassLoader interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "([Ljava/net/URL;Ljava/lang/ClassLoader;)V", Self::init, Default::default()), - JavaMethodProto::new("findClass", "(Ljava/lang/String;)Ljava/lang/Class;", Self::find_class, Default::default()), + JavaMethodProto::new( + "", + "([Ljava/net/URL;Ljava/lang/ClassLoader;)V", + Self::init, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new( + "findClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + Self::find_class, + MethodAccessFlags::PROTECTED, + ), JavaMethodProto::new( "findResource", "(Ljava/lang/String;)Ljava/net/URL;", Self::find_resource, - Default::default(), + MethodAccessFlags::PUBLIC, ), ], fields: vec![JavaFieldProto::new("urls", "[Ljava/net/URL;", Default::default())], @@ -71,13 +82,21 @@ impl URLClassLoader { let resource_name = JavaLangString::from_rust_string(jvm, &resource_name).await?; let resource: ClassInstanceRef = jvm - .invoke_virtual(&this, "findResource", "(Ljava/lang/String;)Ljava/net/URL;", (resource_name,)) + .invoke_virtual( + &this, + "java/net/URLClassLoader", + "findResource", + "(Ljava/lang/String;)Ljava/net/URL;", + (resource_name,), + ) .await?; if resource.is_null() { return Ok(None.into()); } - let stream = jvm.invoke_virtual(&resource, "openStream", "()Ljava/io/InputStream;", ()).await?; + let stream = jvm + .invoke_virtual(&resource, "java/net/URL", "openStream", "()Ljava/io/InputStream;", ()) + .await?; let bytes = JavaIoInputStream::read_until_end(jvm, &stream).await?; let length = bytes.len() as i32; @@ -87,6 +106,7 @@ impl URLClassLoader { let class = jvm .invoke_virtual( &this, + "java/net/URLClassLoader", "defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;", (name, bytes_java.clone(), 0, length), @@ -110,7 +130,7 @@ impl URLClassLoader { let urls: Vec> = jvm.load_array(&urls, 0, jvm.array_length(&urls).await? as _).await?; for url in urls { - let file = jvm.invoke_virtual(&url, "getFile", "()Ljava/lang/String;", ()).await?; + let file = jvm.invoke_virtual(&url, "java/net/URL", "getFile", "()Ljava/lang/String;", ()).await?; let file = JavaLangString::to_rust_string(jvm, &file).await?; let metadata = runtime.metadata(&file).await; @@ -148,10 +168,13 @@ impl URLClassLoader { let jar_url_str = format!("jar:file:{file}!/{name_str}"); // TODO url might not be file let jar_url = JavaLangString::from_rust_string(jvm, &jar_url_str).await?; let jar_url = jvm.new_class("java/net/URL", "(Ljava/lang/String;)V", (jar_url,)).await?; - let connection: ClassInstanceRef = - jvm.invoke_virtual(&jar_url, "openConnection", "()Ljava/net/URLConnection;", ()).await?; + let connection: ClassInstanceRef = jvm + .invoke_virtual(&jar_url, "java/net/URL", "openConnection", "()Ljava/net/URLConnection;", ()) + .await?; - let entry: ClassInstanceRef = jvm.invoke_virtual(&connection, "getJarEntry", "()Ljava/util/jar/JarEntry;", ()).await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual(&connection, "java/net/JarURLConnection", "getJarEntry", "()Ljava/util/jar/JarEntry;", ()) + .await?; if !entry.is_null() { return Ok(jar_url.into()); diff --git a/java_runtime/src/classes/java/net/url_connection.rs b/java_runtime/src/classes/java/net/url_connection.rs index 40a31480..a4b53cf0 100644 --- a/java_runtime/src/classes/java/net/url_connection.rs +++ b/java_runtime/src/classes/java/net/url_connection.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::MethodAccessFlags; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -18,8 +19,13 @@ impl URLConnection { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/net/URL;)V", Self::init, Default::default()), - JavaMethodProto::new("getInputStream", "()Ljava/io/InputStream;", Self::get_input_stream, Default::default()), + JavaMethodProto::new("", "(Ljava/net/URL;)V", Self::init, MethodAccessFlags::PROTECTED), + JavaMethodProto::new( + "getInputStream", + "()Ljava/io/InputStream;", + Self::get_input_stream, + MethodAccessFlags::PUBLIC, + ), ], fields: vec![JavaFieldProto::new("url", "Ljava/net/URL;", Default::default())], access_flags: Default::default(), diff --git a/java_runtime/src/classes/java/net/url_stream_handler.rs b/java_runtime/src/classes/java/net/url_stream_handler.rs index 0b95d515..5c2f3456 100644 --- a/java_runtime/src/classes/java/net/url_stream_handler.rs +++ b/java_runtime/src/classes/java/net/url_stream_handler.rs @@ -1,6 +1,6 @@ use alloc::{borrow::ToOwned, string::ToString, vec}; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use url::Url; use java_class_proto::JavaMethodProto; @@ -21,14 +21,19 @@ impl URLStreamHandler { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new_abstract("openConnection", "(Ljava/net/URL;)Ljava/net/URLConnection;", Default::default()), - JavaMethodProto::new("parseURL", "(Ljava/net/URL;Ljava/lang/String;II)V", Self::parse_url, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PROTECTED), + JavaMethodProto::new_abstract("openConnection", "(Ljava/net/URL;)Ljava/net/URLConnection;", MethodAccessFlags::PROTECTED), + JavaMethodProto::new( + "parseURL", + "(Ljava/net/URL;Ljava/lang/String;II)V", + Self::parse_url, + MethodAccessFlags::PROTECTED, + ), JavaMethodProto::new( "setURL", "(Ljava/net/URL;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V", Self::set_url, - Default::default(), + MethodAccessFlags::PROTECTED, ), ], fields: vec![], @@ -64,6 +69,7 @@ impl URLStreamHandler { let _: () = jvm .invoke_virtual( &url, + "java/net/URL", "set", "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V", (protocol, host, port, file, r#ref), @@ -109,6 +115,7 @@ impl URLStreamHandler { let _: () = jvm .invoke_virtual( &this, + "java/net/URLStreamHandler", "setURL", "(Ljava/net/URL;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V", (url, protocol, host, port, file, None), diff --git a/java_runtime/src/classes/java/text/date_format.rs b/java_runtime/src/classes/java/text/date_format.rs index eea38e37..c52d5dc9 100644 --- a/java_runtime/src/classes/java/text/date_format.rs +++ b/java_runtime/src/classes/java/text/date_format.rs @@ -314,6 +314,7 @@ impl DateFormat { let date: ClassInstanceRef = ClassInstanceRef::new(object.instance); jvm.invoke_virtual( &this, + "java/text/DateFormat", "format", "(Ljava/util/Date;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (date, buffer, position), @@ -335,12 +336,14 @@ impl DateFormat { let buffer: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/text/DateFormat", "format", "(Ljava/util/Date;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (date, buffer, position), ) .await?; - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn parse( @@ -356,14 +359,17 @@ impl DateFormat { let date: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/text/DateFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/util/Date;", (source, position.clone()), ) .await?; - let index: i32 = jvm.invoke_virtual(&position, "getIndex", "()I", ()).await?; + let index: i32 = jvm.invoke_virtual(&position, "java/text/ParsePosition", "getIndex", "()I", ()).await?; if index == 0 { - let error_index: i32 = jvm.invoke_virtual(&position, "getErrorIndex", "()I", ()).await?; + let error_index: i32 = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "getErrorIndex", "()I", ()) + .await?; let message = JavaLangString::from_rust_string(jvm, "Unparseable date").await?; let exception: ClassInstanceRef = jvm .new_class("java/text/ParseException", "(Ljava/lang/String;I)V", (message, error_index)) @@ -384,6 +390,7 @@ impl DateFormat { let date: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/text/DateFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/util/Date;", (source, position), @@ -540,23 +547,25 @@ impl DateFormat { async fn get_time_zone(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let calendar: ClassInstanceRef = jvm.get_field(&this, "calendar", "Ljava/util/Calendar;").await?; - jvm.invoke_virtual(&calendar, "getTimeZone", "()Ljava/util/TimeZone;", ()).await + jvm.invoke_virtual(&calendar, "java/util/Calendar", "getTimeZone", "()Ljava/util/TimeZone;", ()) + .await } async fn set_time_zone(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, time_zone: ClassInstanceRef) -> Result<()> { let calendar: ClassInstanceRef = jvm.get_field(&this, "calendar", "Ljava/util/Calendar;").await?; - jvm.invoke_virtual(&calendar, "setTimeZone", "(Ljava/util/TimeZone;)V", (time_zone,)) + jvm.invoke_virtual(&calendar, "java/util/Calendar", "setTimeZone", "(Ljava/util/TimeZone;)V", (time_zone,)) .await } async fn is_lenient(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let calendar: ClassInstanceRef = jvm.get_field(&this, "calendar", "Ljava/util/Calendar;").await?; - jvm.invoke_virtual(&calendar, "isLenient", "()Z", ()).await + jvm.invoke_virtual(&calendar, "java/util/Calendar", "isLenient", "()Z", ()).await } async fn set_lenient(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, lenient: bool) -> Result<()> { let calendar: ClassInstanceRef = jvm.get_field(&this, "calendar", "Ljava/util/Calendar;").await?; - jvm.invoke_virtual(&calendar, "setLenient", "(Z)V", (lenient,)).await + jvm.invoke_virtual(&calendar, "java/util/Calendar", "setLenient", "(Z)V", (lenient,)) + .await } async fn clone(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { diff --git a/java_runtime/src/classes/java/text/decimal_format.rs b/java_runtime/src/classes/java/text/decimal_format.rs index d4a7ea57..cc52068d 100644 --- a/java_runtime/src/classes/java/text/decimal_format.rs +++ b/java_runtime/src/classes/java/text/decimal_format.rs @@ -246,7 +246,8 @@ impl DecimalFormat { return Err(jvm.exception("java/lang/NullPointerException", "pattern").await); } let _: () = jvm.invoke_special(&this, "java/text/NumberFormat", "", "()V", ()).await?; - jvm.invoke_virtual(&this, "applyPattern", "(Ljava/lang/String;)V", (pattern,)).await + jvm.invoke_virtual(&this, "java/text/DecimalFormat", "applyPattern", "(Ljava/lang/String;)V", (pattern,)) + .await } async fn apply_pattern(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, pattern: ClassInstanceRef) -> Result<()> { @@ -338,25 +339,47 @@ impl DecimalFormat { } formatted.push_str(&suffix); - let base: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; - let field: i32 = jvm.invoke_virtual(&position, "getField", "()I", ()).await?; + let base: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; + let field: i32 = jvm.invoke_virtual(&position, "java/text/FieldPosition", "getField", "()I", ()).await?; if field == 0 { let begin = base + prefix.encode_utf16().count() as i32; - let _: () = jvm.invoke_virtual(&position, "setBeginIndex", "(I)V", (begin,)).await?; let _: () = jvm - .invoke_virtual(&position, "setEndIndex", "(I)V", (begin + integer.encode_utf16().count() as i32,)) + .invoke_virtual(&position, "java/text/FieldPosition", "setBeginIndex", "(I)V", (begin,)) + .await?; + let _: () = jvm + .invoke_virtual( + &position, + "java/text/FieldPosition", + "setEndIndex", + "(I)V", + (begin + integer.encode_utf16().count() as i32,), + ) .await?; } else if field == 1 && !fraction.is_empty() { let begin = base + prefix.encode_utf16().count() as i32 + integer.encode_utf16().count() as i32 + 1; - let _: () = jvm.invoke_virtual(&position, "setBeginIndex", "(I)V", (begin,)).await?; let _: () = jvm - .invoke_virtual(&position, "setEndIndex", "(I)V", (begin + fraction.encode_utf16().count() as i32,)) + .invoke_virtual(&position, "java/text/FieldPosition", "setBeginIndex", "(I)V", (begin,)) + .await?; + let _: () = jvm + .invoke_virtual( + &position, + "java/text/FieldPosition", + "setEndIndex", + "(I)V", + (begin + fraction.encode_utf16().count() as i32,), + ) .await?; } let text = JavaLangString::from_rust_string(jvm, &formatted).await?; - jvm.invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (text,)) - .await + jvm.invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (text,), + ) + .await } async fn format_double( @@ -373,7 +396,13 @@ impl DecimalFormat { if value.is_nan() { let text = JavaLangString::from_rust_string(jvm, "NaN").await?; return jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (text,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (text,), + ) .await; } @@ -435,13 +464,17 @@ impl DecimalFormat { utf16_index += character.len_utf16(); } utf16_indices.push(utf16_index); - let start: i32 = jvm.invoke_virtual(&position, "getIndex", "()I", ()).await?; + let start: i32 = jvm.invoke_virtual(&position, "java/text/ParsePosition", "getIndex", "()I", ()).await?; if start < 0 { - let _: () = jvm.invoke_virtual(&position, "setErrorIndex", "(I)V", (start,)).await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setErrorIndex", "(I)V", (start,)) + .await?; return Ok(ClassInstanceRef::new(None)); } let Some(start_index) = utf16_indices.iter().position(|index| *index == start as usize) else { - let _: () = jvm.invoke_virtual(&position, "setErrorIndex", "(I)V", (start,)).await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setErrorIndex", "(I)V", (start,)) + .await?; return Ok(ClassInstanceRef::new(None)); }; @@ -462,7 +495,9 @@ impl DecimalFormat { index += positive_prefix.len(); false } else { - let _: () = jvm.invoke_virtual(&position, "setErrorIndex", "(I)V", (start,)).await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setErrorIndex", "(I)V", (start,)) + .await?; return Ok(ClassInstanceRef::new(None)); }; @@ -488,7 +523,13 @@ impl DecimalFormat { } if digits == 0 { let _: () = jvm - .invoke_virtual(&position, "setErrorIndex", "(I)V", (utf16_indices[index] as i32,)) + .invoke_virtual( + &position, + "java/text/ParsePosition", + "setErrorIndex", + "(I)V", + (utf16_indices[index] as i32,), + ) .await?; return Ok(ClassInstanceRef::new(None)); } @@ -503,7 +544,13 @@ impl DecimalFormat { false } else { let _: () = jvm - .invoke_virtual(&position, "setErrorIndex", "(I)V", (utf16_indices[index] as i32,)) + .invoke_virtual( + &position, + "java/text/ParsePosition", + "setErrorIndex", + "(I)V", + (utf16_indices[index] as i32,), + ) .await?; return Ok(ClassInstanceRef::new(None)); } @@ -511,7 +558,13 @@ impl DecimalFormat { let suffix = if prefix_negative { &negative_suffix } else { &positive_suffix }; if !characters[index..].starts_with(suffix) { let _: () = jvm - .invoke_virtual(&position, "setErrorIndex", "(I)V", (utf16_indices[index] as i32,)) + .invoke_virtual( + &position, + "java/text/ParsePosition", + "setErrorIndex", + "(I)V", + (utf16_indices[index] as i32,), + ) .await?; return Ok(ClassInstanceRef::new(None)); } @@ -523,15 +576,21 @@ impl DecimalFormat { } let Ok(mut value) = normalized.parse::() else { - let _: () = jvm.invoke_virtual(&position, "setErrorIndex", "(I)V", (start,)).await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setErrorIndex", "(I)V", (start,)) + .await?; return Ok(ClassInstanceRef::new(None)); }; let multiplier: i32 = jvm.get_field(&this, "multiplier", "I").await?; if multiplier != 0 { value /= f64::from(multiplier); } - let _: () = jvm.invoke_virtual(&position, "setIndex", "(I)V", (utf16_indices[index] as i32,)).await?; - let _: () = jvm.invoke_virtual(&position, "setErrorIndex", "(I)V", (-1,)).await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setIndex", "(I)V", (utf16_indices[index] as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setErrorIndex", "(I)V", (-1,)) + .await?; if multiplier == 1 && !decimal diff --git a/java_runtime/src/classes/java/text/format.rs b/java_runtime/src/classes/java/text/format.rs index 887e4eaa..94b82a76 100644 --- a/java_runtime/src/classes/java/text/format.rs +++ b/java_runtime/src/classes/java/text/format.rs @@ -67,12 +67,14 @@ impl Format { let buffer: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/text/Format", "format", "(Ljava/lang/Object;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (object, buffer, position), ) .await?; - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn parse_object( @@ -89,14 +91,17 @@ impl Format { let result: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/text/Format", "parseObject", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Object;", (source, position.clone()), ) .await?; - let index: i32 = jvm.invoke_virtual(&position, "getIndex", "()I", ()).await?; + let index: i32 = jvm.invoke_virtual(&position, "java/text/ParsePosition", "getIndex", "()I", ()).await?; if index == 0 { - let error_index: i32 = jvm.invoke_virtual(&position, "getErrorIndex", "()I", ()).await?; + let error_index: i32 = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "getErrorIndex", "()I", ()) + .await?; let message = JavaLangString::from_rust_string(jvm, "Format.parseObject(String) failed").await?; let exception: ClassInstanceRef = jvm .new_class("java/text/ParseException", "(Ljava/lang/String;I)V", (message, error_index)) diff --git a/java_runtime/src/classes/java/text/number_format.rs b/java_runtime/src/classes/java/text/number_format.rs index dc3463e7..741d002f 100644 --- a/java_runtime/src/classes/java/text/number_format.rs +++ b/java_runtime/src/classes/java/text/number_format.rs @@ -245,10 +245,11 @@ impl NumberFormat { || jvm.is_instance(&**object, "java/lang/Integer") || jvm.is_instance(&**object, "java/lang/Long") { - let value: i64 = jvm.invoke_virtual(&object, "longValue", "()J", ()).await?; + let value: i64 = jvm.invoke_virtual(&object, "java/lang/Number", "longValue", "()J", ()).await?; return jvm .invoke_virtual( &this, + "java/text/NumberFormat", "format", "(JLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (value, buffer, position), @@ -256,9 +257,10 @@ impl NumberFormat { .await; } - let value: f64 = jvm.invoke_virtual(&object, "doubleValue", "()D", ()).await?; + let value: f64 = jvm.invoke_virtual(&object, "java/lang/Number", "doubleValue", "()D", ()).await?; jvm.invoke_virtual( &this, + "java/text/NumberFormat", "format", "(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (value, buffer, position), @@ -272,12 +274,14 @@ impl NumberFormat { let buffer: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/text/NumberFormat", "format", "(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (value, buffer, position), ) .await?; - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn format_long(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: i64) -> Result> { @@ -286,12 +290,14 @@ impl NumberFormat { let buffer: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/text/NumberFormat", "format", "(JLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (value, buffer, position), ) .await?; - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn parse( @@ -307,14 +313,17 @@ impl NumberFormat { let result: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/text/NumberFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;", (source, position.clone()), ) .await?; - let index: i32 = jvm.invoke_virtual(&position, "getIndex", "()I", ()).await?; + let index: i32 = jvm.invoke_virtual(&position, "java/text/ParsePosition", "getIndex", "()I", ()).await?; if index == 0 { - let error_index: i32 = jvm.invoke_virtual(&position, "getErrorIndex", "()I", ()).await?; + let error_index: i32 = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "getErrorIndex", "()I", ()) + .await?; let message = JavaLangString::from_rust_string(jvm, "Unparseable number").await?; let exception: ClassInstanceRef = jvm .new_class("java/text/ParseException", "(Ljava/lang/String;I)V", (message, error_index)) @@ -335,6 +344,7 @@ impl NumberFormat { let number: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/text/NumberFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;", (source, position), @@ -400,7 +410,9 @@ impl NumberFormat { .new_class("java/text/DecimalFormat", "(Ljava/lang/String;)V", (pattern,)) .await? .into(); - let _: () = jvm.invoke_virtual(&format, "setParseIntegerOnly", "(Z)V", (true,)).await?; + let _: () = jvm + .invoke_virtual(&format, "java/text/NumberFormat", "setParseIntegerOnly", "(Z)V", (true,)) + .await?; Ok(format) } diff --git a/java_runtime/src/classes/java/text/simple_date_format.rs b/java_runtime/src/classes/java/text/simple_date_format.rs index 5216307b..f7fc60e5 100644 --- a/java_runtime/src/classes/java/text/simple_date_format.rs +++ b/java_runtime/src/classes/java/text/simple_date_format.rs @@ -427,10 +427,12 @@ impl SimpleDateFormat { let Some(tokens) = Self::tokenize_pattern(&pattern) else { return Err(jvm.exception("java/lang/IllegalArgumentException", "Illegal pattern").await); }; - let time: i64 = jvm.invoke_virtual(&date, "getTime", "()J", ()).await?; + let time: i64 = jvm.invoke_virtual(&date, "java/util/Date", "getTime", "()J", ()).await?; let calendar: ClassInstanceRef = jvm.get_field(&this, "calendar", "Ljava/util/Calendar;").await?; - let time_zone: ClassInstanceRef = jvm.invoke_virtual(&calendar, "getTimeZone", "()Ljava/util/TimeZone;", ()).await?; - let offset: i32 = jvm.invoke_virtual(&time_zone, "getRawOffset", "()I", ()).await?; + let time_zone: ClassInstanceRef = jvm + .invoke_virtual(&calendar, "java/util/Calendar", "getTimeZone", "()Ljava/util/TimeZone;", ()) + .await?; + let offset: i32 = jvm.invoke_virtual(&time_zone, "java/util/TimeZone", "getRawOffset", "()I", ()).await?; let Some(adjusted) = time.checked_add(i64::from(offset)) else { return Err(jvm.exception("java/lang/IllegalArgumentException", "date out of range").await); }; @@ -455,8 +457,8 @@ impl SimpleDateFormat { let short_months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; let weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; let short_weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - let requested_field: i32 = jvm.invoke_virtual(&position, "getField", "()I", ()).await?; - let base: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; + let requested_field: i32 = jvm.invoke_virtual(&position, "java/text/FieldPosition", "getField", "()I", ()).await?; + let base: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; let mut field_position_set = false; let mut formatted = RustString::new(); for token in tokens { @@ -510,9 +512,17 @@ impl SimpleDateFormat { _ => return Err(jvm.exception("java/lang/IllegalArgumentException", "Illegal pattern").await), } if !field_position_set && Self::date_field(character) == Some(requested_field) { - let _: () = jvm.invoke_virtual(&position, "setBeginIndex", "(I)V", (base + begin,)).await?; let _: () = jvm - .invoke_virtual(&position, "setEndIndex", "(I)V", (base + formatted.encode_utf16().count() as i32,)) + .invoke_virtual(&position, "java/text/FieldPosition", "setBeginIndex", "(I)V", (base + begin,)) + .await?; + let _: () = jvm + .invoke_virtual( + &position, + "java/text/FieldPosition", + "setEndIndex", + "(I)V", + (base + formatted.encode_utf16().count() as i32,), + ) .await?; field_position_set = true; } @@ -520,8 +530,14 @@ impl SimpleDateFormat { } } let text = JavaLangString::from_rust_string(jvm, &formatted).await?; - jvm.invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (text,)) - .await + jvm.invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (text,), + ) + .await } async fn parse( @@ -548,27 +564,43 @@ impl SimpleDateFormat { utf16_index += character.len_utf16(); } utf16_indices.push(utf16_index); - let start: i32 = jvm.invoke_virtual(&position, "getIndex", "()I", ()).await?; + let start: i32 = jvm.invoke_virtual(&position, "java/text/ParsePosition", "getIndex", "()I", ()).await?; if start < 0 { - let _: () = jvm.invoke_virtual(&position, "setErrorIndex", "(I)V", (start,)).await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setErrorIndex", "(I)V", (start,)) + .await?; return Ok(ClassInstanceRef::new(None)); } let Some(start_index) = utf16_indices.iter().position(|index| *index == start as usize) else { - let _: () = jvm.invoke_virtual(&position, "setErrorIndex", "(I)V", (start,)).await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setErrorIndex", "(I)V", (start,)) + .await?; return Ok(ClassInstanceRef::new(None)); }; let calendar: ClassInstanceRef = jvm.get_field(&this, "calendar", "Ljava/util/Calendar;").await?; - let time_zone: ClassInstanceRef = jvm.invoke_virtual(&calendar, "getTimeZone", "()Ljava/util/TimeZone;", ()).await?; - let offset: i32 = jvm.invoke_virtual(&time_zone, "getRawOffset", "()I", ()).await?; + let time_zone: ClassInstanceRef = jvm + .invoke_virtual(&calendar, "java/util/Calendar", "getTimeZone", "()Ljava/util/TimeZone;", ()) + .await?; + let offset: i32 = jvm.invoke_virtual(&time_zone, "java/util/TimeZone", "getRawOffset", "()I", ()).await?; match Self::parse_timestamp(&tokens, &characters, start_index, offset) { Ok((timestamp, index)) => { - let _: () = jvm.invoke_virtual(&position, "setIndex", "(I)V", (utf16_indices[index] as i32,)).await?; - let _: () = jvm.invoke_virtual(&position, "setErrorIndex", "(I)V", (-1,)).await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setIndex", "(I)V", (utf16_indices[index] as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setErrorIndex", "(I)V", (-1,)) + .await?; Ok(jvm.new_class("java/util/Date", "(J)V", (timestamp,)).await?.into()) } Err(error_index) => { let _: () = jvm - .invoke_virtual(&position, "setErrorIndex", "(I)V", (utf16_indices[error_index] as i32,)) + .invoke_virtual( + &position, + "java/text/ParsePosition", + "setErrorIndex", + "(I)V", + (utf16_indices[error_index] as i32,), + ) .await?; Ok(ClassInstanceRef::new(None)) } diff --git a/java_runtime/src/classes/java/util/abstract_collection.rs b/java_runtime/src/classes/java/util/abstract_collection.rs index 4705258d..4818c2ea 100644 --- a/java_runtime/src/classes/java/util/abstract_collection.rs +++ b/java_runtime/src/classes/java/util/abstract_collection.rs @@ -57,7 +57,7 @@ impl AbstractCollection { async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.util.AbstractCollection::isEmpty({this:?})"); - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/AbstractCollection", "size", "()I", ()).await?; Ok(size == 0) } @@ -65,14 +65,20 @@ impl AbstractCollection { async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { tracing::debug!("java.util.AbstractCollection::contains({this:?}, {element:?})"); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&this, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractCollection", "iterator", "()Ljava/util/Iterator;", ()) + .await?; loop { - let has_next: bool = jvm.invoke_virtual(&iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; if !has_next { return Ok(false); } - let current: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let current: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; if Self::object_equals(jvm, &element, ¤t).await? { return Ok(true); } @@ -82,15 +88,21 @@ impl AbstractCollection { async fn to_array(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result>> { tracing::debug!("java.util.AbstractCollection::toArray({this:?})"); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&this, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractCollection", "iterator", "()Ljava/util/Iterator;", ()) + .await?; let mut elements = vec![]; loop { - let has_next: bool = jvm.invoke_virtual(&iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; if !has_next { break; } - let current: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let current: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; elements.push(current); } @@ -114,7 +126,9 @@ impl AbstractCollection { return Err(jvm.exception("java/lang/NullPointerException", "array").await); } - let snapshot: ClassInstanceRef> = jvm.invoke_virtual(&this, "toArray", "()[Ljava/lang/Object;", ()).await?; + let snapshot: ClassInstanceRef> = jvm + .invoke_virtual(&this, "java/util/AbstractCollection", "toArray", "()[Ljava/lang/Object;", ()) + .await?; let size = jvm.array_length(&snapshot).await?; let elements: alloc::vec::Vec> = if size == 0 { alloc::vec::Vec::new() @@ -165,10 +179,14 @@ impl AbstractCollection { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - let elements: ClassInstanceRef> = jvm.invoke_virtual(&collection, "toArray", "()[Ljava/lang/Object;", ()).await?; + let elements: ClassInstanceRef> = jvm + .invoke_virtual(&collection, &collection.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let size = jvm.array_length(&elements).await?; for element in jvm.load_array::>(&elements, 0, size).await? { - let contains: bool = jvm.invoke_virtual(&this, "contains", "(Ljava/lang/Object;)Z", (element,)).await?; + let contains: bool = jvm + .invoke_virtual(&this, "java/util/AbstractCollection", "contains", "(Ljava/lang/Object;)Z", (element,)) + .await?; if !contains { return Ok(false); } @@ -184,11 +202,15 @@ impl AbstractCollection { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - let elements: ClassInstanceRef> = jvm.invoke_virtual(&collection, "toArray", "()[Ljava/lang/Object;", ()).await?; + let elements: ClassInstanceRef> = jvm + .invoke_virtual(&collection, &collection.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let size = jvm.array_length(&elements).await?; let mut modified = false; for element in jvm.load_array::>(&elements, 0, size).await? { - modified |= jvm.invoke_virtual::<_, bool>(&this, "add", "(Ljava/lang/Object;)Z", (element,)).await?; + modified |= jvm + .invoke_virtual::<_, bool>(&this, "java/util/AbstractCollection", "add", "(Ljava/lang/Object;)Z", (element,)) + .await?; } Ok(modified) @@ -201,7 +223,9 @@ impl AbstractCollection { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - let elements: ClassInstanceRef> = jvm.invoke_virtual(&this, "toArray", "()[Ljava/lang/Object;", ()).await?; + let elements: ClassInstanceRef> = jvm + .invoke_virtual(&this, "java/util/AbstractCollection", "toArray", "()[Ljava/lang/Object;", ()) + .await?; let size = jvm.array_length(&elements).await?; let same_collection = this.identity() == collection.identity(); let mut modified = false; @@ -209,12 +233,24 @@ impl AbstractCollection { let remove = if same_collection { true } else { - jvm.invoke_virtual(&collection, "contains", "(Ljava/lang/Object;)Z", (element.clone(),)) - .await? + jvm.invoke_virtual( + &collection, + &collection.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (element.clone(),), + ) + .await? }; if remove { while jvm - .invoke_virtual::<_, bool>(&this, "remove", "(Ljava/lang/Object;)Z", (element.clone(),)) + .invoke_virtual::<_, bool>( + &this, + "java/util/AbstractCollection", + "remove", + "(Ljava/lang/Object;)Z", + (element.clone(),), + ) .await? { modified = true; @@ -235,16 +271,30 @@ impl AbstractCollection { return Ok(false); } - let elements: ClassInstanceRef> = jvm.invoke_virtual(&this, "toArray", "()[Ljava/lang/Object;", ()).await?; + let elements: ClassInstanceRef> = jvm + .invoke_virtual(&this, "java/util/AbstractCollection", "toArray", "()[Ljava/lang/Object;", ()) + .await?; let size = jvm.array_length(&elements).await?; let mut modified = false; for element in jvm.load_array::>(&elements, 0, size).await? { let retain: bool = jvm - .invoke_virtual(&collection, "contains", "(Ljava/lang/Object;)Z", (element.clone(),)) + .invoke_virtual( + &collection, + &collection.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (element.clone(),), + ) .await?; if !retain { while jvm - .invoke_virtual::<_, bool>(&this, "remove", "(Ljava/lang/Object;)Z", (element.clone(),)) + .invoke_virtual::<_, bool>( + &this, + "java/util/AbstractCollection", + "remove", + "(Ljava/lang/Object;)Z", + (element.clone(),), + ) .await? { modified = true; @@ -265,36 +315,74 @@ impl AbstractCollection { let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?.into(); let open = JavaLangString::from_rust_string(jvm, "[").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (open,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (open,), + ) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractCollection", "iterator", "()Ljava/util/Iterator;", ()) .await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&this, "iterator", "()Ljava/util/Iterator;", ()).await?; let mut first = true; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { if first { first = false; } else { let separator = JavaLangString::from_rust_string(jvm, ", ").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (separator,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (separator,), + ) .await?; } - let element: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let element: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; if !element.is_null() && element.identity() == this.identity() { let recursive = JavaLangString::from_rust_string(jvm, "(this Collection)").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (recursive,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (recursive,), + ) .await?; } else { let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/Object;)Ljava/lang/StringBuffer;", (element,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/Object;)Ljava/lang/StringBuffer;", + (element,), + ) .await?; } } let close = JavaLangString::from_rust_string(jvm, "]").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (close,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (close,), + ) .await?; - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn object_equals(jvm: &Jvm, left: &ClassInstanceRef, right: &ClassInstanceRef) -> Result { @@ -306,6 +394,7 @@ impl AbstractCollection { return Ok(false); } - jvm.invoke_virtual(left, "equals", "(Ljava/lang/Object;)Z", (right.clone(),)).await + jvm.invoke_virtual(left, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) + .await } } diff --git a/java_runtime/src/classes/java/util/abstract_list.rs b/java_runtime/src/classes/java/util/abstract_list.rs index ab85e6b2..6b497668 100644 --- a/java_runtime/src/classes/java/util/abstract_list.rs +++ b/java_runtime/src/classes/java/util/abstract_list.rs @@ -44,8 +44,10 @@ impl AbstractList { } async fn add(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; - let _: () = jvm.invoke_virtual(&this, "add", "(ILjava/lang/Object;)V", (size, element)).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/AbstractList", "size", "()I", ()).await?; + let _: () = jvm + .invoke_virtual(&this, "java/util/AbstractList", "add", "(ILjava/lang/Object;)V", (size, element)) + .await?; Ok(true) } @@ -66,7 +68,7 @@ impl AbstractList { ) -> Result { tracing::debug!("java.util.AbstractList::addAll({this:?}, {index:?}, {collection:?})"); - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/AbstractList", "size", "()I", ()).await?; if index < 0 || index > size { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "index").await); } @@ -74,7 +76,9 @@ impl AbstractList { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - let elements: ClassInstanceRef> = jvm.invoke_virtual(&collection, "toArray", "()[Ljava/lang/Object;", ()).await?; + let elements: ClassInstanceRef> = jvm + .invoke_virtual(&collection, &collection.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let count = jvm.array_length(&elements).await?; for (offset, element) in jvm .load_array::>(&elements, 0, count) @@ -83,7 +87,13 @@ impl AbstractList { .enumerate() { let _: () = jvm - .invoke_virtual(&this, "add", "(ILjava/lang/Object;)V", (index + offset as i32, element)) + .invoke_virtual( + &this, + "java/util/AbstractList", + "add", + "(ILjava/lang/Object;)V", + (index + offset as i32, element), + ) .await?; } @@ -93,16 +103,18 @@ impl AbstractList { async fn last_index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { tracing::debug!("java.util.AbstractList::lastIndexOf({this:?}, {element:?})"); - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/AbstractList", "size", "()I", ()).await?; for index in (0..size).rev() { - let current: ClassInstanceRef = jvm.invoke_virtual(&this, "get", "(I)Ljava/lang/Object;", (index,)).await?; + let current: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractList", "get", "(I)Ljava/lang/Object;", (index,)) + .await?; if element.is_null() { if current.is_null() { return Ok(index); } } else if !current.is_null() && jvm - .invoke_virtual::<_, bool>(&element, "equals", "(Ljava/lang/Object;)Z", (current,)) + .invoke_virtual::<_, bool>(&element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) .await? { return Ok(index); @@ -113,16 +125,18 @@ impl AbstractList { } async fn index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/AbstractList", "size", "()I", ()).await?; for index in 0..size { - let current: ClassInstanceRef = jvm.invoke_virtual(&this, "get", "(I)Ljava/lang/Object;", (index,)).await?; + let current: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractList", "get", "(I)Ljava/lang/Object;", (index,)) + .await?; if element.is_null() { if current.is_null() { return Ok(index); } } else if !current.is_null() && jvm - .invoke_virtual::<_, bool>(&element, "equals", "(Ljava/lang/Object;)Z", (current,)) + .invoke_virtual::<_, bool>(&element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) .await? { return Ok(index); @@ -149,7 +163,7 @@ impl AbstractList { } async fn sub_list(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, from: i32, to: i32) -> Result> { - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/AbstractList", "size", "()I", ()).await?; if from < 0 || to > size { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "subList range").await); } @@ -178,23 +192,31 @@ impl AbstractList { return Ok(false); } - let left: ClassInstanceRef = jvm.invoke_virtual(&this, "listIterator", "()Ljava/util/ListIterator;", ()).await?; - let right: ClassInstanceRef = jvm.invoke_virtual(&other, "listIterator", "()Ljava/util/ListIterator;", ()).await?; + let left: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractList", "listIterator", "()Ljava/util/ListIterator;", ()) + .await?; + let right: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "listIterator", "()Ljava/util/ListIterator;", ()) + .await?; loop { - let left_has_next: bool = jvm.invoke_virtual(&left, "hasNext", "()Z", ()).await?; - let right_has_next: bool = jvm.invoke_virtual(&right, "hasNext", "()Z", ()).await?; + let left_has_next: bool = jvm.invoke_virtual(&left, &left.class_definition().name(), "hasNext", "()Z", ()).await?; + let right_has_next: bool = jvm.invoke_virtual(&right, &right.class_definition().name(), "hasNext", "()Z", ()).await?; if !left_has_next || !right_has_next { return Ok(left_has_next == right_has_next); } - let left_element: ClassInstanceRef = jvm.invoke_virtual(&left, "next", "()Ljava/lang/Object;", ()).await?; - let right_element: ClassInstanceRef = jvm.invoke_virtual(&right, "next", "()Ljava/lang/Object;", ()).await?; + let left_element: ClassInstanceRef = jvm + .invoke_virtual(&left, &left.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let right_element: ClassInstanceRef = jvm + .invoke_virtual(&right, &right.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let equal = if left_element.is_null() { right_element.is_null() } else if right_element.is_null() { false } else { - jvm.invoke_virtual::<_, bool>(&left_element, "equals", "(Ljava/lang/Object;)Z", (right_element,)) + jvm.invoke_virtual::<_, bool>(&left_element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (right_element,)) .await? }; if !equal { @@ -204,14 +226,21 @@ impl AbstractList { } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let iterator: ClassInstanceRef = jvm.invoke_virtual(&this, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractList", "iterator", "()Ljava/util/Iterator;", ()) + .await?; let mut hash = 1i32; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let element: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let element: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let element_hash = if element.is_null() { 0 } else { - jvm.invoke_virtual(&element, "hashCode", "()I", ()).await? + jvm.invoke_virtual(&element, "java/lang/Object", "hashCode", "()I", ()).await? }; hash = hash.wrapping_mul(31).wrapping_add(element_hash); } @@ -263,7 +292,7 @@ impl AbstractListItr { } async fn init(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, list: ClassInstanceRef, index: i32) -> Result<()> { - let size: i32 = jvm.invoke_virtual(&list, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&list, &list.class_definition().name(), "size", "()I", ()).await?; if index < 0 || index > size { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "list iterator index").await); } @@ -276,16 +305,25 @@ impl AbstractListItr { async fn has_next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; - Ok(cursor < jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?) + Ok(cursor + < jvm + .invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await?) } async fn next(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result> { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; - if cursor >= jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await? { + if cursor + >= jvm + .invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await? + { return Err(jvm.exception("java/util/NoSuchElementException", "AbstractList iterator exhausted").await); } - let element = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (cursor,)).await?; + let element = jvm + .invoke_virtual(&list, &list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (cursor,)) + .await?; jvm.put_field(&mut this, "cursor", "I", cursor + 1).await?; jvm.put_field(&mut this, "lastReturned", "I", cursor).await?; Ok(element) @@ -302,7 +340,9 @@ impl AbstractListItr { } let index = cursor - 1; let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - let element = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (index,)).await?; + let element = jvm + .invoke_virtual(&list, &list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (index,)) + .await?; jvm.put_field(&mut this, "cursor", "I", index).await?; jvm.put_field(&mut this, "lastReturned", "I", index).await?; Ok(element) @@ -322,7 +362,15 @@ impl AbstractListItr { return Err(jvm.exception("java/lang/IllegalStateException", "iterator state").await); } let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&list, "remove", "(I)Ljava/lang/Object;", (last_returned,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "remove", + "(I)Ljava/lang/Object;", + (last_returned,), + ) + .await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; if last_returned < cursor { jvm.put_field(&mut this, "cursor", "I", cursor - 1).await?; @@ -337,7 +385,13 @@ impl AbstractListItr { } let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (last_returned, element)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (last_returned, element), + ) .await?; Ok(()) } @@ -345,7 +399,9 @@ impl AbstractListItr { async fn add(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, element: ClassInstanceRef) -> Result<()> { let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - let _: () = jvm.invoke_virtual(&list, "add", "(ILjava/lang/Object;)V", (cursor, element)).await?; + let _: () = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(ILjava/lang/Object;)V", (cursor, element)) + .await?; jvm.put_field(&mut this, "cursor", "I", cursor + 1).await?; jvm.put_field(&mut this, "lastReturned", "I", -1).await } diff --git a/java_runtime/src/classes/java/util/abstract_list_sub_list.rs b/java_runtime/src/classes/java/util/abstract_list_sub_list.rs index 300a4c49..1938540c 100644 --- a/java_runtime/src/classes/java/util/abstract_list_sub_list.rs +++ b/java_runtime/src/classes/java/util/abstract_list_sub_list.rs @@ -86,7 +86,8 @@ impl AbstractListSubList { } let root: ClassInstanceRef = jvm.get_field(&this, "root", "Ljava/util/List;").await?; let offset: i32 = jvm.get_field(&this, "offset", "I").await?; - jvm.invoke_virtual(&root, "get", "(I)Ljava/lang/Object;", (offset + index,)).await + jvm.invoke_virtual(&root, &root.class_definition().name(), "get", "(I)Ljava/lang/Object;", (offset + index,)) + .await } async fn set( @@ -102,13 +103,21 @@ impl AbstractListSubList { } let root: ClassInstanceRef = jvm.get_field(&this, "root", "Ljava/util/List;").await?; let offset: i32 = jvm.get_field(&this, "offset", "I").await?; - jvm.invoke_virtual(&root, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (offset + index, element)) - .await + jvm.invoke_virtual( + &root, + &root.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (offset + index, element), + ) + .await } async fn add(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { let size: i32 = jvm.get_field(&this, "size", "I").await?; - let _: () = jvm.invoke_virtual(&this, "add", "(ILjava/lang/Object;)V", (size, element)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/util/AbstractList$SubList", "add", "(ILjava/lang/Object;)V", (size, element)) + .await?; Ok(true) } @@ -120,15 +129,27 @@ impl AbstractListSubList { let root: ClassInstanceRef = jvm.get_field(&this, "root", "Ljava/util/List;").await?; let offset: i32 = jvm.get_field(&this, "offset", "I").await?; let _: () = jvm - .invoke_virtual(&root, "add", "(ILjava/lang/Object;)V", (offset + index, element)) + .invoke_virtual( + &root, + &root.class_definition().name(), + "add", + "(ILjava/lang/Object;)V", + (offset + index, element), + ) .await?; Self::update_sizes(jvm, this, 1).await } async fn add_all(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, collection: ClassInstanceRef) -> Result { let size: i32 = jvm.get_field(&this, "size", "I").await?; - jvm.invoke_virtual(&this, "addAll", "(ILjava/util/Collection;)Z", (size, collection)) - .await + jvm.invoke_virtual( + &this, + "java/util/AbstractList$SubList", + "addAll", + "(ILjava/util/Collection;)Z", + (size, collection), + ) + .await } async fn add_all_at( @@ -145,17 +166,27 @@ impl AbstractListSubList { if collection.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - if jvm.invoke_virtual::<_, i32>(&collection, "size", "()I", ()).await? == 0 { + if jvm + .invoke_virtual::<_, i32>(&collection, &collection.class_definition().name(), "size", "()I", ()) + .await? + == 0 + { return Ok(false); } let root: ClassInstanceRef = jvm.get_field(&this, "root", "Ljava/util/List;").await?; let offset: i32 = jvm.get_field(&this, "offset", "I").await?; - let old_root_size: i32 = jvm.invoke_virtual(&root, "size", "()I", ()).await?; + let old_root_size: i32 = jvm.invoke_virtual(&root, &root.class_definition().name(), "size", "()I", ()).await?; let modified: bool = jvm - .invoke_virtual(&root, "addAll", "(ILjava/util/Collection;)Z", (offset + index, collection)) + .invoke_virtual( + &root, + &root.class_definition().name(), + "addAll", + "(ILjava/util/Collection;)Z", + (offset + index, collection), + ) .await?; if modified { - let new_root_size: i32 = jvm.invoke_virtual(&root, "size", "()I", ()).await?; + let new_root_size: i32 = jvm.invoke_virtual(&root, &root.class_definition().name(), "size", "()I", ()).await?; Self::update_sizes(jvm, this, new_root_size - old_root_size).await?; } Ok(modified) @@ -168,28 +199,42 @@ impl AbstractListSubList { } let root: ClassInstanceRef = jvm.get_field(&this, "root", "Ljava/util/List;").await?; let offset: i32 = jvm.get_field(&this, "offset", "I").await?; - let removed = jvm.invoke_virtual(&root, "remove", "(I)Ljava/lang/Object;", (offset + index,)).await?; + let removed = jvm + .invoke_virtual( + &root, + &root.class_definition().name(), + "remove", + "(I)Ljava/lang/Object;", + (offset + index,), + ) + .await?; Self::update_sizes(jvm, this, -1).await?; Ok(removed) } async fn remove_object(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { - let index: i32 = jvm.invoke_virtual(&this, "indexOf", "(Ljava/lang/Object;)I", (element,)).await?; + let index: i32 = jvm + .invoke_virtual(&this, "java/util/AbstractList$SubList", "indexOf", "(Ljava/lang/Object;)I", (element,)) + .await?; if index < 0 { return Ok(false); } - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "remove", "(I)Ljava/lang/Object;", (index,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractList$SubList", "remove", "(I)Ljava/lang/Object;", (index,)) + .await?; Ok(true) } async fn index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { let size: i32 = jvm.get_field(&this, "size", "I").await?; for index in 0..size { - let current: ClassInstanceRef = jvm.invoke_virtual(&this, "get", "(I)Ljava/lang/Object;", (index,)).await?; + let current: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractList$SubList", "get", "(I)Ljava/lang/Object;", (index,)) + .await?; if (element.is_null() && current.is_null()) || (!element.is_null() && jvm - .invoke_virtual::<_, bool>(&element, "equals", "(Ljava/lang/Object;)Z", (current,)) + .invoke_virtual::<_, bool>(&element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) .await?) { return Ok(index); @@ -201,11 +246,13 @@ impl AbstractListSubList { async fn last_index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { let size: i32 = jvm.get_field(&this, "size", "I").await?; for index in (0..size).rev() { - let current: ClassInstanceRef = jvm.invoke_virtual(&this, "get", "(I)Ljava/lang/Object;", (index,)).await?; + let current: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractList$SubList", "get", "(I)Ljava/lang/Object;", (index,)) + .await?; if (element.is_null() && current.is_null()) || (!element.is_null() && jvm - .invoke_virtual::<_, bool>(&element, "equals", "(Ljava/lang/Object;)Z", (current,)) + .invoke_virtual::<_, bool>(&element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) .await?) { return Ok(index); @@ -216,7 +263,9 @@ impl AbstractListSubList { async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { while jvm.get_field::(&this, "size", "I").await? > 0 { - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "remove", "(I)Ljava/lang/Object;", (0,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractList$SubList", "remove", "(I)Ljava/lang/Object;", (0,)) + .await?; } Ok(()) } diff --git a/java_runtime/src/classes/java/util/abstract_map.rs b/java_runtime/src/classes/java/util/abstract_map.rs index c964d23b..025f638b 100644 --- a/java_runtime/src/classes/java/util/abstract_map.rs +++ b/java_runtime/src/classes/java/util/abstract_map.rs @@ -40,7 +40,7 @@ impl AbstractMap { async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.util.AbstractMap::isEmpty({this:?})"); - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/AbstractMap", "size", "()I", ()).await?; Ok(size == 0) } @@ -55,14 +55,28 @@ impl AbstractMap { return Ok(()); } - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - let entries: ClassInstanceRef> = jvm.invoke_virtual(&entry_set, "toArray", "()[Ljava/lang/Object;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let entries: ClassInstanceRef> = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let count = jvm.array_length(&entries).await?; for entry in jvm.load_array::>(&entries, 0, count).await? { - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&this, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &this, + "java/util/AbstractMap", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } @@ -76,32 +90,51 @@ impl AbstractMap { if this.identity() == other.identity() { return Ok(true); } - let this_size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; - let other_size: i32 = jvm.invoke_virtual(&other, "size", "()I", ()).await?; + let this_size: i32 = jvm.invoke_virtual(&this, "java/util/AbstractMap", "size", "()I", ()).await?; + let other_size: i32 = jvm.invoke_virtual(&other, &other.class_definition().name(), "size", "()I", ()).await?; if this_size != other_size { return Ok(false); } let comparison: Result = async { - let entries: ClassInstanceRef = jvm.invoke_virtual(&this, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractMap", "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; let other_value: ClassInstanceRef = jvm - .invoke_virtual(&other, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) + .invoke_virtual( + &other, + &other.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),), + ) .await?; if value.is_null() { if !other_value.is_null() || !jvm - .invoke_virtual::<_, bool>(&other, "containsKey", "(Ljava/lang/Object;)Z", (key,)) + .invoke_virtual::<_, bool>(&other, &other.class_definition().name(), "containsKey", "(Ljava/lang/Object;)Z", (key,)) .await? { return Ok(false); } } else if !jvm - .invoke_virtual::<_, bool>(&value, "equals", "(Ljava/lang/Object;)Z", (other_value,)) + .invoke_virtual::<_, bool>(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_value,)) .await? { return Ok(false); @@ -122,12 +155,21 @@ impl AbstractMap { } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let entries: ClassInstanceRef = jvm.invoke_virtual(&this, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entries, "iterator", "()Ljava/util/Iterator;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractMap", "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let mut hash = 0i32; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - hash = hash.wrapping_add(jvm.invoke_virtual::<_, i32>(&entry, "hashCode", "()I", ()).await?); + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + hash = hash.wrapping_add(jvm.invoke_virtual::<_, i32>(&entry, "java/lang/Object", "hashCode", "()I", ()).await?); } Ok(hash) } @@ -136,52 +178,114 @@ impl AbstractMap { let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?.into(); let open = JavaLangString::from_rust_string(jvm, "{").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (open,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (open,), + ) + .await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractMap", "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) .await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&this, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entries, "iterator", "()Ljava/util/Iterator;", ()).await?; let mut first = true; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { if first { first = false; } else { let separator = JavaLangString::from_rust_string(jvm, ", ").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (separator,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (separator,), + ) .await?; } - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; if !key.is_null() && key.identity() == this.identity() { let recursive = JavaLangString::from_rust_string(jvm, "(this Map)").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (recursive,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (recursive,), + ) .await?; } else { let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/Object;)Ljava/lang/StringBuffer;", (key,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/Object;)Ljava/lang/StringBuffer;", + (key,), + ) .await?; } let equals = JavaLangString::from_rust_string(jvm, "=").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (equals,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (equals,), + ) .await?; if !value.is_null() && value.identity() == this.identity() { let recursive = JavaLangString::from_rust_string(jvm, "(this Map)").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (recursive,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (recursive,), + ) .await?; } else { let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/Object;)Ljava/lang/StringBuffer;", (value,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/Object;)Ljava/lang/StringBuffer;", + (value,), + ) .await?; } } let close = JavaLangString::from_rust_string(jvm, "}").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (close,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (close,), + ) .await?; - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } } diff --git a/java_runtime/src/classes/java/util/abstract_set.rs b/java_runtime/src/classes/java/util/abstract_set.rs index c6674b08..53fdf62d 100644 --- a/java_runtime/src/classes/java/util/abstract_set.rs +++ b/java_runtime/src/classes/java/util/abstract_set.rs @@ -43,11 +43,18 @@ impl AbstractSet { if !jvm.is_instance(other.as_ref(), "java/util/Set") { return Ok(false); } - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; - if jvm.invoke_virtual::<_, i32>(&other, "size", "()I", ()).await? != size { + let size: i32 = jvm.invoke_virtual(&this, "java/util/AbstractSet", "size", "()I", ()).await?; + if jvm + .invoke_virtual::<_, i32>(&other, &other.class_definition().name(), "size", "()I", ()) + .await? + != size + { return Ok(false); } - match jvm.invoke_virtual(&this, "containsAll", "(Ljava/util/Collection;)Z", (other,)).await { + match jvm + .invoke_virtual(&this, "java/util/AbstractSet", "containsAll", "(Ljava/util/Collection;)Z", (other,)) + .await + { Ok(equal) => Ok(equal), Err(JavaError::JavaException(exception)) if jvm.is_instance(&*exception, "java/lang/ClassCastException") || jvm.is_instance(&*exception, "java/lang/NullPointerException") => @@ -59,12 +66,19 @@ impl AbstractSet { } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let iterator: ClassInstanceRef = jvm.invoke_virtual(&this, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/AbstractSet", "iterator", "()Ljava/util/Iterator;", ()) + .await?; let mut hash = 0i32; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let element: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let element: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; if !element.is_null() { - hash = hash.wrapping_add(jvm.invoke_virtual::<_, i32>(&element, "hashCode", "()I", ()).await?); + hash = hash.wrapping_add(jvm.invoke_virtual::<_, i32>(&element, "java/lang/Object", "hashCode", "()I", ()).await?); } } Ok(hash) diff --git a/java_runtime/src/classes/java/util/array_list.rs b/java_runtime/src/classes/java/util/array_list.rs index 695d8616..4588c999 100644 --- a/java_runtime/src/classes/java/util/array_list.rs +++ b/java_runtime/src/classes/java/util/array_list.rs @@ -16,27 +16,27 @@ impl ArrayList { parent_class: Some("java/util/AbstractList"), interfaces: vec!["java/lang/Cloneable", "java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(I)V", Self::init_with_capacity, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(I)V", Self::init_with_capacity, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/util/Collection;)V", Self::init_from_collection, MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("add", "(Ljava/lang/Object;)Z", Self::add, Default::default()), - JavaMethodProto::new("add", "(ILjava/lang/Object;)V", Self::add_at, Default::default()), - JavaMethodProto::new("get", "(I)Ljava/lang/Object;", Self::get, Default::default()), - JavaMethodProto::new("set", "(ILjava/lang/Object;)Ljava/lang/Object;", Self::set, Default::default()), - JavaMethodProto::new("remove", "(I)Ljava/lang/Object;", Self::remove, Default::default()), - JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove_object, Default::default()), - JavaMethodProto::new("size", "()I", Self::size, Default::default()), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), - JavaMethodProto::new("indexOf", "(Ljava/lang/Object;)I", Self::index_of, Default::default()), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("toArray", "()[Ljava/lang/Object;", Self::to_array, Default::default()), - JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, Default::default()), + JavaMethodProto::new("add", "(Ljava/lang/Object;)Z", Self::add, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("add", "(ILjava/lang/Object;)V", Self::add_at, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("get", "(I)Ljava/lang/Object;", Self::get, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("set", "(ILjava/lang/Object;)Ljava/lang/Object;", Self::set, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("remove", "(I)Ljava/lang/Object;", Self::remove, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove_object, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("indexOf", "(Ljava/lang/Object;)I", Self::index_of, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("toArray", "()[Ljava/lang/Object;", Self::to_array, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "listIterator", "()Ljava/util/ListIterator;", @@ -95,9 +95,13 @@ impl ArrayList { if collection.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - let size: i32 = jvm.invoke_virtual(&collection, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&collection, &collection.class_definition().name(), "size", "()I", ()) + .await?; let _: () = jvm.invoke_special(&this, "java/util/ArrayList", "", "(I)V", (size,)).await?; - let _: bool = jvm.invoke_virtual(&this, "addAll", "(Ljava/util/Collection;)Z", (collection,)).await?; + let _: bool = jvm + .invoke_virtual(&this, "java/util/ArrayList", "addAll", "(Ljava/util/Collection;)Z", (collection,)) + .await?; Ok(()) } @@ -207,12 +211,16 @@ impl ArrayList { async fn remove_object(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { tracing::debug!("java.util.ArrayList::remove({this:?}, {element:?})"); - let index: i32 = jvm.invoke_virtual(&this, "indexOf", "(Ljava/lang/Object;)I", (element,)).await?; + let index: i32 = jvm + .invoke_virtual(&this, "java/util/ArrayList", "indexOf", "(Ljava/lang/Object;)I", (element,)) + .await?; if index < 0 { return Ok(false); } - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "remove", "(I)Ljava/lang/Object;", (index,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/ArrayList", "remove", "(I)Ljava/lang/Object;", (index,)) + .await?; Ok(true) } @@ -234,7 +242,9 @@ impl ArrayList { async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { tracing::debug!("java.util.ArrayList::contains({this:?}, {element:?})"); - let index: i32 = jvm.invoke_virtual(&this, "indexOf", "(Ljava/lang/Object;)I", (element,)).await?; + let index: i32 = jvm + .invoke_virtual(&this, "java/util/ArrayList", "indexOf", "(Ljava/lang/Object;)I", (element,)) + .await?; Ok(index >= 0) } @@ -334,7 +344,8 @@ impl ArrayList { return Ok(false); } - jvm.invoke_virtual(left, "equals", "(Ljava/lang/Object;)Z", (right.clone(),)).await + jvm.invoke_virtual(left, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) + .await } async fn copy_to_array(jvm: &Jvm, source: &ClassInstanceRef>, len: i32) -> Result>> { diff --git a/java_runtime/src/classes/java/util/array_list_itr.rs b/java_runtime/src/classes/java/util/array_list_itr.rs index 684db14d..4bdf077e 100644 --- a/java_runtime/src/classes/java/util/array_list_itr.rs +++ b/java_runtime/src/classes/java/util/array_list_itr.rs @@ -52,7 +52,7 @@ impl ArrayListItr { async fn init(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, list: ClassInstanceRef, index: i32) -> Result<()> { tracing::debug!("java.util.ArrayList$Itr::({this:?}, {list:?}, {index:?})"); - let size: i32 = jvm.invoke_virtual(&list, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&list, &list.class_definition().name(), "size", "()I", ()).await?; if index < 0 || index > size { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "list iterator index").await); } @@ -65,18 +65,20 @@ impl ArrayListItr { async fn has_next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; - let size: i32 = jvm.invoke_virtual(&list, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&list, &list.class_definition().name(), "size", "()I", ()).await?; Ok(cursor < size) } async fn next(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result> { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; - let size: i32 = jvm.invoke_virtual(&list, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&list, &list.class_definition().name(), "size", "()I", ()).await?; if cursor >= size { return Err(jvm.exception("java/util/NoSuchElementException", "ArrayList iterator exhausted").await); } - let element = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (cursor,)).await?; + let element = jvm + .invoke_virtual(&list, &list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (cursor,)) + .await?; jvm.put_field(&mut this, "cursor", "I", cursor + 1).await?; jvm.put_field(&mut this, "lastReturned", "I", cursor).await?; Ok(element) @@ -93,7 +95,9 @@ impl ArrayListItr { } let index = cursor - 1; let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - let element = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (index,)).await?; + let element = jvm + .invoke_virtual(&list, &list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (index,)) + .await?; jvm.put_field(&mut this, "cursor", "I", index).await?; jvm.put_field(&mut this, "lastReturned", "I", index).await?; Ok(element) @@ -113,7 +117,15 @@ impl ArrayListItr { return Err(jvm.exception("java/lang/IllegalStateException", "iterator state").await); } let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&list, "remove", "(I)Ljava/lang/Object;", (last_returned,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "remove", + "(I)Ljava/lang/Object;", + (last_returned,), + ) + .await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; if last_returned < cursor { jvm.put_field(&mut this, "cursor", "I", cursor - 1).await?; @@ -128,7 +140,13 @@ impl ArrayListItr { } let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (last_returned, element)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (last_returned, element), + ) .await?; Ok(()) } @@ -136,7 +154,9 @@ impl ArrayListItr { async fn add(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, element: ClassInstanceRef) -> Result<()> { let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - let _: () = jvm.invoke_virtual(&list, "add", "(ILjava/lang/Object;)V", (cursor, element)).await?; + let _: () = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(ILjava/lang/Object;)V", (cursor, element)) + .await?; jvm.put_field(&mut this, "cursor", "I", cursor + 1).await?; jvm.put_field(&mut this, "lastReturned", "I", -1).await } diff --git a/java_runtime/src/classes/java/util/arrays.rs b/java_runtime/src/classes/java/util/arrays.rs index 0dddd285..66dfdcbb 100644 --- a/java_runtime/src/classes/java/util/arrays.rs +++ b/java_runtime/src/classes/java/util/arrays.rs @@ -435,10 +435,18 @@ impl Arrays { if !jvm.is_instance(left.as_ref(), "java/lang/Comparable") { return Err(jvm.exception("java/lang/ClassCastException", &left.class_definition().name()).await); } - jvm.invoke_virtual(left, "compareTo", "(Ljava/lang/Object;)I", (right.clone(),)).await + jvm.invoke_virtual( + left, + &left.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (right.clone(),), + ) + .await } else { jvm.invoke_virtual( comparator, + &comparator.class_definition().name(), "compare", "(Ljava/lang/Object;Ljava/lang/Object;)I", (left.clone(), right.clone()), @@ -688,7 +696,10 @@ impl Arrays { if !right.is_null() { return Ok(false); } - } else if !jvm.invoke_virtual::<_, bool>(&left, "equals", "(Ljava/lang/Object;)Z", (right,)).await? { + } else if !jvm + .invoke_virtual::<_, bool>(&left, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (right,)) + .await? + { return Ok(false); } } diff --git a/java_runtime/src/classes/java/util/calendar.rs b/java_runtime/src/classes/java/util/calendar.rs index 0e9338f1..b66b23f3 100644 --- a/java_runtime/src/classes/java/util/calendar.rs +++ b/java_runtime/src/classes/java/util/calendar.rs @@ -22,30 +22,45 @@ impl Calendar { parent_class: Some("java/lang/Object"), interfaces: vec!["java/io/Serializable", "java/lang/Cloneable"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("getInstance", "()Ljava/util/Calendar;", Self::get_instance, MethodAccessFlags::STATIC), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PROTECTED), + JavaMethodProto::new( + "getInstance", + "()Ljava/util/Calendar;", + Self::get_instance, + MethodAccessFlags::PUBLIC | MethodAccessFlags::STATIC, + ), JavaMethodProto::new( "getInstance", "(Ljava/util/TimeZone;)Ljava/util/Calendar;", Self::get_instance_with_time_zone, - MethodAccessFlags::STATIC, + MethodAccessFlags::PUBLIC | MethodAccessFlags::STATIC, ), - JavaMethodProto::new("setTime", "(Ljava/util/Date;)V", Self::set_time, Default::default()), - JavaMethodProto::new("getTime", "()Ljava/util/Date;", Self::get_time, Default::default()), - JavaMethodProto::new("setTimeInMillis", "(J)V", Self::set_time_in_millis, Default::default()), - JavaMethodProto::new("getTimeInMillis", "()J", Self::get_time_in_millis, Default::default()), - JavaMethodProto::new("getTimeZone", "()Ljava/util/TimeZone;", Self::get_time_zone, Default::default()), - JavaMethodProto::new("setTimeZone", "(Ljava/util/TimeZone;)V", Self::set_time_zone, Default::default()), - JavaMethodProto::new("isLenient", "()Z", Self::is_lenient, Default::default()), - JavaMethodProto::new("setLenient", "(Z)V", Self::set_lenient, Default::default()), - JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, Default::default()), - JavaMethodProto::new("hashCode", "()I", Self::hash_code, Default::default()), - JavaMethodProto::new("before", "(Ljava/lang/Object;)Z", Self::before, Default::default()), - JavaMethodProto::new("after", "(Ljava/lang/Object;)Z", Self::after, Default::default()), - JavaMethodProto::new("set", "(II)V", Self::set, Default::default()), - JavaMethodProto::new("get", "(I)I", Self::get, Default::default()), - JavaMethodProto::new_abstract("computeTime", "()V", Default::default()), - JavaMethodProto::new_abstract("computeFields", "()V", Default::default()), + JavaMethodProto::new( + "setTime", + "(Ljava/util/Date;)V", + Self::set_time, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "getTime", + "()Ljava/util/Date;", + Self::get_time, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new("setTimeInMillis", "(J)V", Self::set_time_in_millis, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getTimeInMillis", "()J", Self::get_time_in_millis, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getTimeZone", "()Ljava/util/TimeZone;", Self::get_time_zone, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("setTimeZone", "(Ljava/util/TimeZone;)V", Self::set_time_zone, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("isLenient", "()Z", Self::is_lenient, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("setLenient", "(Z)V", Self::set_lenient, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("before", "(Ljava/lang/Object;)Z", Self::before, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("after", "(Ljava/lang/Object;)Z", Self::after, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("set", "(II)V", Self::set, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("get", "(I)I", Self::get, MethodAccessFlags::PUBLIC), + JavaMethodProto::new_abstract("computeTime", "()V", MethodAccessFlags::PROTECTED | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("computeFields", "()V", MethodAccessFlags::PROTECTED | MethodAccessFlags::ABSTRACT), ], fields: vec![ JavaFieldProto::new("time", "J", Default::default()), @@ -53,7 +68,7 @@ impl Calendar { JavaFieldProto::new("timeZone", "Ljava/util/TimeZone;", Default::default()), JavaFieldProto::new("lenient", "Z", Default::default()), ], - access_flags: ClassAccessFlags::ABSTRACT, + access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::ABSTRACT, } } @@ -107,10 +122,10 @@ impl Calendar { return Err(jvm.exception("java/lang/NullPointerException", "date").await); } - let time: i64 = jvm.invoke_virtual(&date, "getTime", "()J", ()).await?; + let time: i64 = jvm.invoke_virtual(&date, "java/util/Date", "getTime", "()J", ()).await?; jvm.put_field(&mut this, "time", "J", time).await?; - let _: () = jvm.invoke_virtual(&this, "computeFields", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&this, "java/util/Calendar", "computeFields", "()V", ()).await?; Ok(()) } @@ -128,7 +143,7 @@ impl Calendar { tracing::debug!("java.util.Calendar::setTimeInMillis({this:?}, {time:?})"); jvm.put_field(&mut this, "time", "J", time).await?; - jvm.invoke_virtual(&this, "computeFields", "()V", ()).await + jvm.invoke_virtual(&this, "java/util/Calendar", "computeFields", "()V", ()).await } async fn get_time_in_millis(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -147,7 +162,7 @@ impl Calendar { return Err(jvm.exception("java/lang/NullPointerException", "timeZone").await); } jvm.put_field(&mut this, "timeZone", "Ljava/util/TimeZone;", time_zone).await?; - jvm.invoke_virtual(&this, "computeFields", "()V", ()).await + jvm.invoke_virtual(&this, "java/util/Calendar", "computeFields", "()V", ()).await } async fn is_lenient(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -182,15 +197,22 @@ impl Calendar { let time_zone: ClassInstanceRef = jvm.get_field(&this, "timeZone", "Ljava/util/TimeZone;").await?; let other_time_zone: ClassInstanceRef = jvm.get_field(&other, "timeZone", "Ljava/util/TimeZone;").await?; - let raw_offset: i32 = jvm.invoke_virtual(&time_zone, "getRawOffset", "()I", ()).await?; - let other_raw_offset: i32 = jvm.invoke_virtual(&other_time_zone, "getRawOffset", "()I", ()).await?; + let raw_offset: i32 = jvm.invoke_virtual(&time_zone, "java/util/TimeZone", "getRawOffset", "()I", ()).await?; + let other_raw_offset: i32 = jvm + .invoke_virtual(&other_time_zone, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?; if raw_offset != other_raw_offset { return Ok(false); } - let id: ClassInstanceRef = jvm.invoke_virtual(&time_zone, "getID", "()Ljava/lang/String;", ()).await?; - let other_id: ClassInstanceRef = jvm.invoke_virtual(&other_time_zone, "getID", "()Ljava/lang/String;", ()).await?; - jvm.invoke_virtual(&id, "equals", "(Ljava/lang/Object;)Z", (other_id,)).await + let id: ClassInstanceRef = jvm + .invoke_virtual(&time_zone, "java/util/TimeZone", "getID", "()Ljava/lang/String;", ()) + .await?; + let other_id: ClassInstanceRef = jvm + .invoke_virtual(&other_time_zone, "java/util/TimeZone", "getID", "()Ljava/lang/String;", ()) + .await?; + jvm.invoke_virtual(&id, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_id,)) + .await } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -198,9 +220,11 @@ impl Calendar { let time: i64 = jvm.get_field(&this, "time", "J").await?; let time_zone: ClassInstanceRef = jvm.get_field(&this, "timeZone", "Ljava/util/TimeZone;").await?; - let raw_offset: i32 = jvm.invoke_virtual(&time_zone, "getRawOffset", "()I", ()).await?; - let id: ClassInstanceRef = jvm.invoke_virtual(&time_zone, "getID", "()Ljava/lang/String;", ()).await?; - let id_hash: i32 = jvm.invoke_virtual(&id, "hashCode", "()I", ()).await?; + let raw_offset: i32 = jvm.invoke_virtual(&time_zone, "java/util/TimeZone", "getRawOffset", "()I", ()).await?; + let id: ClassInstanceRef = jvm + .invoke_virtual(&time_zone, "java/util/TimeZone", "getID", "()Ljava/lang/String;", ()) + .await?; + let id_hash: i32 = jvm.invoke_virtual(&id, "java/lang/Object", "hashCode", "()I", ()).await?; let lenient: bool = jvm.get_field(&this, "lenient", "Z").await?; Ok((time ^ ((time as u64 >> 32) as i64)) as i32 ^ raw_offset ^ id_hash ^ if lenient { 1 } else { 0 }) } @@ -241,8 +265,8 @@ impl Calendar { let mut fields = jvm.get_field(&this, "fields", "[I").await?; jvm.store_array(&mut fields, field as usize, vec![value]).await?; - let _: () = jvm.invoke_virtual(&this, "computeTime", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&this, "computeFields", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&this, "java/util/Calendar", "computeTime", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&this, "java/util/Calendar", "computeFields", "()V", ()).await?; Ok(()) } diff --git a/java_runtime/src/classes/java/util/collections.rs b/java_runtime/src/classes/java/util/collections.rs index e7b543da..cfddadc0 100644 --- a/java_runtime/src/classes/java/util/collections.rs +++ b/java_runtime/src/classes/java/util/collections.rs @@ -192,10 +192,18 @@ impl Collections { if !jvm.is_instance(left.as_ref(), "java/lang/Comparable") { return Err(jvm.exception("java/lang/ClassCastException", &left.class_definition().name()).await); } - jvm.invoke_virtual(left, "compareTo", "(Ljava/lang/Object;)I", (right.clone(),)).await + jvm.invoke_virtual( + left, + &left.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (right.clone(),), + ) + .await } else { jvm.invoke_virtual( comparator, + &comparator.class_definition().name(), "compare", "(Ljava/lang/Object;Ljava/lang/Object;)I", (left.clone(), right.clone()), @@ -206,10 +214,16 @@ impl Collections { async fn write_list(jvm: &Jvm, list: &ClassInstanceRef, elements: ClassInstanceRef>) -> Result<()> { let length = jvm.array_length(&elements).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(list, "listIterator", "()Ljava/util/ListIterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(list, &list.class_definition().name(), "listIterator", "()Ljava/util/ListIterator;", ()) + .await?; for element in jvm.load_array::>(&elements, 0, length).await? { - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let _: () = jvm.invoke_virtual(&iterator, "set", "(Ljava/lang/Object;)V", (element,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "set", "(Ljava/lang/Object;)V", (element,)) + .await?; } Ok(()) } @@ -219,7 +233,9 @@ impl Collections { return Err(jvm.exception("java/lang/NullPointerException", "list").await); } - let elements: ClassInstanceRef> = jvm.invoke_virtual(&list, "toArray", "()[Ljava/lang/Object;", ()).await?; + let elements: ClassInstanceRef> = jvm + .invoke_virtual(&list, &list.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; if comparator.is_null() { let _: () = jvm .invoke_static("java/util/Arrays", "sort", "([Ljava/lang/Object;)V", (elements.clone(),)) @@ -252,10 +268,12 @@ impl Collections { } let mut low = 0i32; - let mut high: i32 = jvm.invoke_virtual(&list, "size", "()I", ()).await?; + let mut high: i32 = jvm.invoke_virtual(&list, &list.class_definition().name(), "size", "()I", ()).await?; while low < high { let middle = low + (high - low) / 2; - let value: ClassInstanceRef = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (middle,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (middle,)) + .await?; let comparison = Self::compare(jvm, &comparator, &value, &key).await?; if comparison < 0 { low = middle + 1; @@ -287,17 +305,35 @@ impl Collections { return Err(jvm.exception("java/lang/NullPointerException", "list").await); } - let size: i32 = jvm.invoke_virtual(&list, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&list, &list.class_definition().name(), "size", "()I", ()).await?; if size < 2 { return Ok(()); } - let forward: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "()Ljava/util/ListIterator;", ()).await?; - let backward: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "(I)Ljava/util/ListIterator;", (size,)).await?; + let forward: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "listIterator", "()Ljava/util/ListIterator;", ()) + .await?; + let backward: ClassInstanceRef = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "listIterator", + "(I)Ljava/util/ListIterator;", + (size,), + ) + .await?; for _ in 0..size / 2 { - let left: ClassInstanceRef = jvm.invoke_virtual(&forward, "next", "()Ljava/lang/Object;", ()).await?; - let right: ClassInstanceRef = jvm.invoke_virtual(&backward, "previous", "()Ljava/lang/Object;", ()).await?; - let _: () = jvm.invoke_virtual(&forward, "set", "(Ljava/lang/Object;)V", (right,)).await?; - let _: () = jvm.invoke_virtual(&backward, "set", "(Ljava/lang/Object;)V", (left,)).await?; + let left: ClassInstanceRef = jvm + .invoke_virtual(&forward, &forward.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let right: ClassInstanceRef = jvm + .invoke_virtual(&backward, &backward.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await?; + let _: () = jvm + .invoke_virtual(&forward, &forward.class_definition().name(), "set", "(Ljava/lang/Object;)V", (right,)) + .await?; + let _: () = jvm + .invoke_virtual(&backward, &backward.class_definition().name(), "set", "(Ljava/lang/Object;)V", (left,)) + .await?; } Ok(()) } @@ -307,10 +343,25 @@ impl Collections { return Err(jvm.exception("java/lang/NullPointerException", "list").await); } - let iterator: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "()Ljava/util/ListIterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let _: () = jvm.invoke_virtual(&iterator, "set", "(Ljava/lang/Object;)V", (element.clone(),)).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "listIterator", "()Ljava/util/ListIterator;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let _: () = jvm + .invoke_virtual( + &iterator, + &iterator.class_definition().name(), + "set", + "(Ljava/lang/Object;)V", + (element.clone(),), + ) + .await?; } Ok(()) } @@ -319,22 +370,38 @@ impl Collections { if source.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "source").await); } - let source_size: i32 = jvm.invoke_virtual(&source, "size", "()I", ()).await?; + let source_size: i32 = jvm.invoke_virtual(&source, &source.class_definition().name(), "size", "()I", ()).await?; if destination.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "destination").await); } - let destination_size: i32 = jvm.invoke_virtual(&destination, "size", "()I", ()).await?; + let destination_size: i32 = jvm + .invoke_virtual(&destination, &destination.class_definition().name(), "size", "()I", ()) + .await?; if source_size > destination_size { return Err(jvm .exception("java/lang/IndexOutOfBoundsException", "source does not fit in destination") .await); } - let elements: ClassInstanceRef> = jvm.invoke_virtual(&source, "toArray", "()[Ljava/lang/Object;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&destination, "listIterator", "()Ljava/util/ListIterator;", ()).await?; + let elements: ClassInstanceRef> = jvm + .invoke_virtual(&source, &source.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &destination, + &destination.class_definition().name(), + "listIterator", + "()Ljava/util/ListIterator;", + (), + ) + .await?; for element in jvm.load_array::>(&elements, 0, source_size as usize).await? { - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let _: () = jvm.invoke_virtual(&iterator, "set", "(Ljava/lang/Object;)V", (element,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "set", "(Ljava/lang/Object;)V", (element,)) + .await?; } Ok(()) } @@ -343,7 +410,9 @@ impl Collections { if list.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "list").await); } - let elements: ClassInstanceRef> = jvm.invoke_virtual(&list, "toArray", "()[Ljava/lang/Object;", ()).await?; + let elements: ClassInstanceRef> = jvm + .invoke_virtual(&list, &list.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let length = jvm.array_length(&elements).await?; if length < 2 { return Ok(()); @@ -353,7 +422,9 @@ impl Collections { } let mut values = jvm.load_array::>(&elements, 0, length).await?; for index in (1..length).rev() { - let swap_index: i32 = jvm.invoke_virtual(&random, "nextInt", "(I)I", ((index + 1) as i32,)).await?; + let swap_index: i32 = jvm + .invoke_virtual(&random, "java/util/Random", "nextInt", "(I)I", ((index + 1) as i32,)) + .await?; if swap_index < 0 || swap_index as usize > index { return Err(jvm.exception("java/lang/ArrayIndexOutOfBoundsException", "random index").await); } @@ -386,14 +457,32 @@ impl Collections { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - let iterator: ClassInstanceRef = jvm.invoke_virtual(&collection, "iterator", "()Ljava/util/Iterator;", ()).await?; - if !jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &collection, + &collection.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + if !jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { return Err(jvm.exception("java/util/NoSuchElementException", "empty collection").await); } - let mut candidate: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let mut candidate: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let next: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let next: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let comparison = Self::compare(jvm, &comparator, &next, &candidate).await?; if (find_minimum && comparison < 0) || (!find_minimum && comparison > 0) { candidate = next; diff --git a/java_runtime/src/classes/java/util/collections_copies_list.rs b/java_runtime/src/classes/java/util/collections_copies_list.rs index 9ccda21d..05bbeb05 100644 --- a/java_runtime/src/classes/java/util/collections_copies_list.rs +++ b/java_runtime/src/classes/java/util/collections_copies_list.rs @@ -62,7 +62,8 @@ impl CollectionsCopiesList { if element.is_null() { return Ok(false); } - jvm.invoke_virtual(&target, "equals", "(Ljava/lang/Object;)Z", (element,)).await + jvm.invoke_virtual(&target, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (element,)) + .await } async fn index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, target: ClassInstanceRef) -> Result { @@ -75,7 +76,7 @@ impl CollectionsCopiesList { } else if element.is_null() { false } else { - jvm.invoke_virtual::<_, bool>(&target, "equals", "(Ljava/lang/Object;)Z", (element,)) + jvm.invoke_virtual::<_, bool>(&target, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (element,)) .await? }; Ok(if equal { 0 } else { -1 }) @@ -92,7 +93,7 @@ impl CollectionsCopiesList { } else if element.is_null() { false } else { - jvm.invoke_virtual::<_, bool>(&target, "equals", "(Ljava/lang/Object;)Z", (element,)) + jvm.invoke_virtual::<_, bool>(&target, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (element,)) .await? }; Ok(if equal { count - 1 } else { -1 }) @@ -124,7 +125,7 @@ impl CollectionsCopiesList { } else if element.is_null() { false } else { - jvm.invoke_virtual::<_, bool>(&target, "equals", "(Ljava/lang/Object;)Z", (element,)) + jvm.invoke_virtual::<_, bool>(&target, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (element,)) .await? }; if !equal { @@ -163,19 +164,30 @@ impl CollectionsCopiesList { } let count: i32 = jvm.get_field(&this, "n", "I").await?; - if jvm.invoke_virtual::<_, i32>(&other, "size", "()I", ()).await? != count { + if jvm + .invoke_virtual::<_, i32>(&other, &other.class_definition().name(), "size", "()I", ()) + .await? + != count + { return Ok(false); } let element: ClassInstanceRef = jvm.get_field(&this, "element", "Ljava/lang/Object;").await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&other, "iterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let current: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let current: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let equal = if element.is_null() { current.is_null() } else if current.is_null() { false } else { - jvm.invoke_virtual::<_, bool>(&element, "equals", "(Ljava/lang/Object;)Z", (current,)) + jvm.invoke_virtual::<_, bool>(&element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) .await? }; if !equal { @@ -191,7 +203,7 @@ impl CollectionsCopiesList { let element_hash = if element.is_null() { 0 } else { - jvm.invoke_virtual(&element, "hashCode", "()I", ()).await? + jvm.invoke_virtual(&element, "java/lang/Object", "hashCode", "()I", ()).await? }; let mut hash = 1i32; for _ in 0..count { diff --git a/java_runtime/src/classes/java/util/collections_empty_list.rs b/java_runtime/src/classes/java/util/collections_empty_list.rs index 49e7760c..82e406ae 100644 --- a/java_runtime/src/classes/java/util/collections_empty_list.rs +++ b/java_runtime/src/classes/java/util/collections_empty_list.rs @@ -79,7 +79,7 @@ impl CollectionsEmptyList { if other.is_null() || !jvm.is_instance(other.as_ref(), "java/util/List") { return Ok(false); } - jvm.invoke_virtual(&other, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&other, &other.class_definition().name(), "isEmpty", "()Z", ()).await } async fn hash_code(_: &Jvm, _: &mut RuntimeContext, _: ClassInstanceRef) -> Result { diff --git a/java_runtime/src/classes/java/util/collections_empty_set.rs b/java_runtime/src/classes/java/util/collections_empty_set.rs index 357a70ba..97bdd55b 100644 --- a/java_runtime/src/classes/java/util/collections_empty_set.rs +++ b/java_runtime/src/classes/java/util/collections_empty_set.rs @@ -44,7 +44,8 @@ impl CollectionsEmptySet { async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, _: ClassInstanceRef) -> Result> { let list: ClassInstanceRef = jvm.get_static_field("java/util/Collections", "EMPTY_LIST", "Ljava/util/List;").await?; - jvm.invoke_virtual(&list, "iterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&list, &list.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await } async fn clear(_: &Jvm, _: &mut RuntimeContext, _: ClassInstanceRef) -> Result<()> { @@ -59,7 +60,7 @@ impl CollectionsEmptySet { if other.is_null() || !jvm.is_instance(other.as_ref(), "java/util/Set") { return Ok(false); } - jvm.invoke_virtual(&other, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&other, &other.class_definition().name(), "isEmpty", "()Z", ()).await } async fn hash_code(_: &Jvm, _: &mut RuntimeContext, _: ClassInstanceRef) -> Result { diff --git a/java_runtime/src/classes/java/util/collections_singleton_set.rs b/java_runtime/src/classes/java/util/collections_singleton_set.rs index 7f131fe7..eaa96bac 100644 --- a/java_runtime/src/classes/java/util/collections_singleton_set.rs +++ b/java_runtime/src/classes/java/util/collections_singleton_set.rs @@ -50,7 +50,8 @@ impl CollectionsSingletonSet { if element.is_null() { return Ok(false); } - jvm.invoke_virtual(&target, "equals", "(Ljava/lang/Object;)Z", (element,)).await + jvm.invoke_virtual(&target, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (element,)) + .await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { @@ -58,7 +59,8 @@ impl CollectionsSingletonSet { let list = jvm .new_class("java/util/Collections$CopiesList", "(ILjava/lang/Object;)V", (1, element)) .await?; - jvm.invoke_virtual(&list, "iterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&list, "java/util/Collections$CopiesList", "iterator", "()Ljava/util/Iterator;", ()) + .await } async fn remove(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, target: ClassInstanceRef) -> Result { @@ -68,7 +70,7 @@ impl CollectionsSingletonSet { } else if element.is_null() { false } else { - jvm.invoke_virtual::<_, bool>(&target, "equals", "(Ljava/lang/Object;)Z", (element,)) + jvm.invoke_virtual::<_, bool>(&target, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (element,)) .await? }; if !equal { @@ -84,11 +86,20 @@ impl CollectionsSingletonSet { if this.identity() == other.identity() { return Ok(true); } - if !jvm.is_instance(other.as_ref(), "java/util/Set") || jvm.invoke_virtual::<_, i32>(&other, "size", "()I", ()).await? != 1 { + if !jvm.is_instance(other.as_ref(), "java/util/Set") + || jvm + .invoke_virtual::<_, i32>(&other, &other.class_definition().name(), "size", "()I", ()) + .await? + != 1 + { return Ok(false); } - let iterator: ClassInstanceRef = jvm.invoke_virtual(&other, "iterator", "()Ljava/util/Iterator;", ()).await?; - let other_element: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let other_element: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let element: ClassInstanceRef = jvm.get_field(&this, "element", "Ljava/lang/Object;").await?; if other_element.is_null() { return Ok(element.is_null()); @@ -96,7 +107,8 @@ impl CollectionsSingletonSet { if element.is_null() { return Ok(false); } - jvm.invoke_virtual(&other_element, "equals", "(Ljava/lang/Object;)Z", (element,)).await + jvm.invoke_virtual(&other_element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (element,)) + .await } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -104,7 +116,7 @@ impl CollectionsSingletonSet { if element.is_null() { Ok(0) } else { - jvm.invoke_virtual(&element, "hashCode", "()I", ()).await + jvm.invoke_virtual(&element, "java/lang/Object", "hashCode", "()I", ()).await } } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_collection.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_collection.rs index 7e480cdf..3ae7adb1 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_collection.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_collection.rs @@ -52,22 +52,39 @@ impl CollectionsUnmodifiableCollection { async fn size(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let collection: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&collection, "size", "()I", ()).await + jvm.invoke_virtual(&collection, &collection.class_definition().name(), "size", "()I", ()) + .await } async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let collection: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&collection, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&collection, &collection.class_definition().name(), "isEmpty", "()Z", ()) + .await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { let collection: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&collection, "contains", "(Ljava/lang/Object;)Z", (element,)).await + jvm.invoke_virtual( + &collection, + &collection.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (element,), + ) + .await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let collection: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&collection, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &collection, + &collection.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableCollection$1", "(Ljava/util/Iterator;)V", (iterator,)) .await? @@ -76,7 +93,8 @@ impl CollectionsUnmodifiableCollection { async fn to_array(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result>> { let collection: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&collection, "toArray", "()[Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&collection, &collection.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await } async fn to_typed_array( @@ -86,19 +104,32 @@ impl CollectionsUnmodifiableCollection { array: ClassInstanceRef>, ) -> Result>> { let collection: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&collection, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (array,)) - .await + jvm.invoke_virtual( + &collection, + &collection.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (array,), + ) + .await } async fn contains_all(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, collection: ClassInstanceRef) -> Result { let backing: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&backing, "containsAll", "(Ljava/util/Collection;)Z", (collection,)) - .await + jvm.invoke_virtual( + &backing, + &backing.class_definition().name(), + "containsAll", + "(Ljava/util/Collection;)Z", + (collection,), + ) + .await } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let collection: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&collection, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&collection, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn add(jvm: &Jvm, _: &mut RuntimeContext, _: ClassInstanceRef, _: ClassInstanceRef) -> Result { diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_collection_iterator.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_collection_iterator.rs index 6d6fc224..bcfadf79 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_collection_iterator.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_collection_iterator.rs @@ -40,12 +40,14 @@ impl CollectionsUnmodifiableCollectionIterator { async fn has_next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/Iterator;").await?; - jvm.invoke_virtual(&iterator, "hasNext", "()Z", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await } async fn next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/Iterator;").await?; - jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await } async fn remove(jvm: &Jvm, _: &mut RuntimeContext, _: ClassInstanceRef) -> Result<()> { diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_list.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_list.rs index 2c1d0e7f..39c5e55d 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_list.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_list.rs @@ -63,32 +63,38 @@ impl CollectionsUnmodifiableList { return Ok(true); } let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - jvm.invoke_virtual(&list, "equals", "(Ljava/lang/Object;)Z", (other,)).await + jvm.invoke_virtual(&list, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other,)) + .await } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - jvm.invoke_virtual(&list, "hashCode", "()I", ()).await + jvm.invoke_virtual(&list, "java/lang/Object", "hashCode", "()I", ()).await } async fn get(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, index: i32) -> Result> { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (index,)).await + jvm.invoke_virtual(&list, &list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (index,)) + .await } async fn index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - jvm.invoke_virtual(&list, "indexOf", "(Ljava/lang/Object;)I", (element,)).await + jvm.invoke_virtual(&list, &list.class_definition().name(), "indexOf", "(Ljava/lang/Object;)I", (element,)) + .await } async fn last_index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - jvm.invoke_virtual(&list, "lastIndexOf", "(Ljava/lang/Object;)I", (element,)).await + jvm.invoke_virtual(&list, &list.class_definition().name(), "lastIndexOf", "(Ljava/lang/Object;)I", (element,)) + .await } async fn list_iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "()Ljava/util/ListIterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "listIterator", "()Ljava/util/ListIterator;", ()) + .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableList$1", "(Ljava/util/ListIterator;)V", (iterator,)) .await? @@ -97,7 +103,15 @@ impl CollectionsUnmodifiableList { async fn list_iterator_at(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, index: i32) -> Result> { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "(I)Ljava/util/ListIterator;", (index,)).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "listIterator", + "(I)Ljava/util/ListIterator;", + (index,), + ) + .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableList$1", "(Ljava/util/ListIterator;)V", (iterator,)) .await? @@ -106,7 +120,9 @@ impl CollectionsUnmodifiableList { async fn sub_list(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, from: i32, to: i32) -> Result> { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/List;").await?; - let sub_list: ClassInstanceRef = jvm.invoke_virtual(&list, "subList", "(II)Ljava/util/List;", (from, to)).await?; + let sub_list: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "subList", "(II)Ljava/util/List;", (from, to)) + .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableList", "(Ljava/util/List;)V", (sub_list,)) .await? diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_list_iterator.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_list_iterator.rs index 3549c84b..a4d8d654 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_list_iterator.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_list_iterator.rs @@ -46,32 +46,38 @@ impl CollectionsUnmodifiableListIterator { async fn has_next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/ListIterator;").await?; - jvm.invoke_virtual(&iterator, "hasNext", "()Z", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await } async fn next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/ListIterator;").await?; - jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await } async fn has_previous(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/ListIterator;").await?; - jvm.invoke_virtual(&iterator, "hasPrevious", "()Z", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), "hasPrevious", "()Z", ()) + .await } async fn previous(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/ListIterator;").await?; - jvm.invoke_virtual(&iterator, "previous", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await } async fn next_index(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/ListIterator;").await?; - jvm.invoke_virtual(&iterator, "nextIndex", "()I", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), "nextIndex", "()I", ()) + .await } async fn previous_index(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/ListIterator;").await?; - jvm.invoke_virtual(&iterator, "previousIndex", "()I", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), "previousIndex", "()I", ()) + .await } async fn remove(jvm: &Jvm, _: &mut RuntimeContext, _: ClassInstanceRef) -> Result<()> { diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_map.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_map.rs index 4819d712..768591dc 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_map.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_map.rs @@ -67,27 +67,36 @@ impl CollectionsUnmodifiableMap { async fn size(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "size", "()I", ()).await } async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - jvm.invoke_virtual(&map, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "isEmpty", "()Z", ()).await } async fn contains_key(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, key: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - jvm.invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (key,)).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "containsKey", "(Ljava/lang/Object;)Z", (key,)) + .await } async fn contains_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - jvm.invoke_virtual(&map, "containsValue", "(Ljava/lang/Object;)Z", (value,)).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "containsValue", "(Ljava/lang/Object;)Z", (value,)) + .await } async fn get(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, key: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - jvm.invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)).await + jvm.invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) + .await } async fn key_set(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result> { @@ -96,7 +105,9 @@ impl CollectionsUnmodifiableMap { return Ok(cached); } let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - let keys: ClassInstanceRef = jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await?; + let keys: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; let wrapped: ClassInstanceRef = jvm .new_class("java/util/Collections$UnmodifiableSet", "(Ljava/util/Set;)V", (keys,)) .await? @@ -111,7 +122,9 @@ impl CollectionsUnmodifiableMap { return Ok(cached); } let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - let values: ClassInstanceRef = jvm.invoke_virtual(&map, "values", "()Ljava/util/Collection;", ()).await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; let wrapped: ClassInstanceRef = jvm .new_class("java/util/Collections$UnmodifiableCollection", "(Ljava/util/Collection;)V", (values,)) .await? @@ -126,7 +139,9 @@ impl CollectionsUnmodifiableMap { return Ok(cached); } let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; let wrapped: ClassInstanceRef = jvm .new_class( "java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet", @@ -144,17 +159,18 @@ impl CollectionsUnmodifiableMap { return Ok(true); } let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - jvm.invoke_virtual(&map, "equals", "(Ljava/lang/Object;)Z", (other,)).await + jvm.invoke_virtual(&map, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other,)) + .await } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - jvm.invoke_virtual(&map, "hashCode", "()I", ()).await + jvm.invoke_virtual(&map, "java/lang/Object", "hashCode", "()I", ()).await } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/Map;").await?; - jvm.invoke_virtual(&map, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&map, "java/lang/Object", "toString", "()Ljava/lang/String;", ()).await } async fn put( diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry.rs index 2b3b4730..550b7953 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry.rs @@ -48,12 +48,14 @@ impl CollectionsUnmodifiableMapEntry { async fn get_key(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let entry: ClassInstanceRef = jvm.get_field(&this, "e", "Ljava/util/Map$Entry;").await?; - jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await } async fn get_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let entry: ClassInstanceRef = jvm.get_field(&this, "e", "Ljava/util/Map$Entry;").await?; - jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await } async fn set_value( @@ -72,33 +74,55 @@ impl CollectionsUnmodifiableMapEntry { if this.identity() == other.identity() { return Ok(true); } - let key: ClassInstanceRef = jvm.invoke_virtual(&this, "getKey", "()Ljava/lang/Object;", ()).await?; - let other_key: ClassInstanceRef = jvm.invoke_virtual(&other, "getKey", "()Ljava/lang/Object;", ()).await?; + let key: ClassInstanceRef = jvm + .invoke_virtual( + &this, + "java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry", + "getKey", + "()Ljava/lang/Object;", + (), + ) + .await?; + let other_key: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; let keys_equal = if key.is_null() { other_key.is_null() } else { - jvm.invoke_virtual::<_, bool>(&key, "equals", "(Ljava/lang/Object;)Z", (other_key,)) + jvm.invoke_virtual::<_, bool>(&key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_key,)) .await? }; if !keys_equal { return Ok(false); } - let value: ClassInstanceRef = jvm.invoke_virtual(&this, "getValue", "()Ljava/lang/Object;", ()).await?; - let other_value: ClassInstanceRef = jvm.invoke_virtual(&other, "getValue", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual( + &this, + "java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry", + "getValue", + "()Ljava/lang/Object;", + (), + ) + .await?; + let other_value: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; if value.is_null() { Ok(other_value.is_null()) } else { - jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (other_value,)).await + jvm.invoke_virtual(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_value,)) + .await } } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let entry: ClassInstanceRef = jvm.get_field(&this, "e", "Ljava/util/Map$Entry;").await?; - jvm.invoke_virtual(&entry, "hashCode", "()I", ()).await + jvm.invoke_virtual(&entry, "java/lang/Object", "hashCode", "()I", ()).await } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let entry: ClassInstanceRef = jvm.get_field(&this, "e", "Ljava/util/Map$Entry;").await?; - jvm.invoke_virtual(&entry, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&entry, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set.rs index 7fb75b70..caffe77c 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set.rs @@ -41,7 +41,9 @@ impl CollectionsUnmodifiableMapEntrySet { async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let set: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&set, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&set, &set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; Ok(jvm .new_class( "java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$1", @@ -54,7 +56,9 @@ impl CollectionsUnmodifiableMapEntrySet { async fn to_array(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result>> { let set: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - let entries: ClassInstanceRef> = jvm.invoke_virtual(&set, "toArray", "()[Ljava/lang/Object;", ()).await?; + let entries: ClassInstanceRef> = jvm + .invoke_virtual(&set, &set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let length = jvm.array_length(&entries).await?; let mut wrapped: Vec> = Vec::with_capacity(length); for entry in jvm.load_array::>(&entries, 0, length).await? { @@ -87,7 +91,9 @@ impl CollectionsUnmodifiableMapEntrySet { let class_name = destination.class_definition().name(); let component_descriptor = class_name.strip_prefix('[').unwrap(); let set: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - let entries: ClassInstanceRef> = jvm.invoke_virtual(&set, "toArray", "()[Ljava/lang/Object;", ()).await?; + let entries: ClassInstanceRef> = jvm + .invoke_virtual(&set, &set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let length = jvm.array_length(&entries).await?; let mut wrapped: Vec> = Vec::with_capacity(length); for entry in jvm.load_array::>(&entries, 0, length).await? { @@ -134,18 +140,38 @@ impl CollectionsUnmodifiableMapEntrySet { .await? .into(); let set: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&set, "contains", "(Ljava/lang/Object;)Z", (safe,)).await + jvm.invoke_virtual(&set, &set.class_definition().name(), "contains", "(Ljava/lang/Object;)Z", (safe,)) + .await } async fn contains_all(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, collection: ClassInstanceRef) -> Result { if collection.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - let iterator: ClassInstanceRef = jvm.invoke_virtual(&collection, "iterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &collection, + &collection.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; if !jvm - .invoke_virtual::<_, bool>(&this, "contains", "(Ljava/lang/Object;)Z", (entry,)) + .invoke_virtual::<_, bool>( + &this, + "java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet", + "contains", + "(Ljava/lang/Object;)Z", + (entry,), + ) .await? { return Ok(false); @@ -161,11 +187,20 @@ impl CollectionsUnmodifiableMapEntrySet { if other.is_null() || !jvm.is_instance(other.as_ref(), "java/util/Set") { return Ok(false); } - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; - let other_size: i32 = jvm.invoke_virtual(&other, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&this, "java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet", "size", "()I", ()) + .await?; + let other_size: i32 = jvm.invoke_virtual(&other, &other.class_definition().name(), "size", "()I", ()).await?; if size != other_size { return Ok(false); } - jvm.invoke_virtual(&this, "containsAll", "(Ljava/util/Collection;)Z", (other,)).await + jvm.invoke_virtual( + &this, + "java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet", + "containsAll", + "(Ljava/util/Collection;)Z", + (other,), + ) + .await } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set_iterator.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set_iterator.rs index a7804c3f..ed25a5f1 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set_iterator.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set_iterator.rs @@ -40,12 +40,15 @@ impl CollectionsUnmodifiableMapEntrySetIterator { async fn has_next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/Iterator;").await?; - jvm.invoke_virtual(&iterator, "hasNext", "()Z", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await } async fn next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let iterator: ClassInstanceRef = jvm.get_field(&this, "i", "Ljava/util/Iterator;").await?; - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; Ok(jvm .new_class( "java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry", diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_set.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_set.rs index 33bb250e..5a3baafe 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_set.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_set.rs @@ -41,11 +41,12 @@ impl CollectionsUnmodifiableSet { return Ok(true); } let set: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&set, "equals", "(Ljava/lang/Object;)Z", (other,)).await + jvm.invoke_virtual(&set, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other,)) + .await } async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let set: ClassInstanceRef = jvm.get_field(&this, "c", "Ljava/util/Collection;").await?; - jvm.invoke_virtual(&set, "hashCode", "()I", ()).await + jvm.invoke_virtual(&set, "java/lang/Object", "hashCode", "()I", ()).await } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_map.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_map.rs index 05362f57..4fbe9a06 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_map.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_map.rs @@ -63,17 +63,20 @@ impl CollectionsUnmodifiableSortedMap { async fn comparator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "sm", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "comparator", "()Ljava/util/Comparator;", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "comparator", "()Ljava/util/Comparator;", ()) + .await } async fn first_key(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "sm", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "firstKey", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "firstKey", "()Ljava/lang/Object;", ()) + .await } async fn last_key(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "sm", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "lastKey", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "lastKey", "()Ljava/lang/Object;", ()) + .await } async fn sub_map( @@ -85,7 +88,13 @@ impl CollectionsUnmodifiableSortedMap { ) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "sm", "Ljava/util/SortedMap;").await?; let range: ClassInstanceRef = jvm - .invoke_virtual(&map, "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (from, to)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "subMap", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", + (from, to), + ) .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableSortedMap", "(Ljava/util/SortedMap;)V", (range,)) @@ -101,7 +110,13 @@ impl CollectionsUnmodifiableSortedMap { ) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "sm", "Ljava/util/SortedMap;").await?; let range: ClassInstanceRef = jvm - .invoke_virtual(&map, "headMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (to,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "headMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (to,), + ) .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableSortedMap", "(Ljava/util/SortedMap;)V", (range,)) @@ -117,7 +132,13 @@ impl CollectionsUnmodifiableSortedMap { ) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "sm", "Ljava/util/SortedMap;").await?; let range: ClassInstanceRef = jvm - .invoke_virtual(&map, "tailMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (from,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "tailMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (from,), + ) .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableSortedMap", "(Ljava/util/SortedMap;)V", (range,)) diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_set.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_set.rs index 3cc3c06f..f4082d74 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_set.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_set.rs @@ -63,17 +63,20 @@ impl CollectionsUnmodifiableSortedSet { async fn comparator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let set: ClassInstanceRef = jvm.get_field(&this, "ss", "Ljava/util/SortedSet;").await?; - jvm.invoke_virtual(&set, "comparator", "()Ljava/util/Comparator;", ()).await + jvm.invoke_virtual(&set, &set.class_definition().name(), "comparator", "()Ljava/util/Comparator;", ()) + .await } async fn first(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let set: ClassInstanceRef = jvm.get_field(&this, "ss", "Ljava/util/SortedSet;").await?; - jvm.invoke_virtual(&set, "first", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&set, &set.class_definition().name(), "first", "()Ljava/lang/Object;", ()) + .await } async fn last(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let set: ClassInstanceRef = jvm.get_field(&this, "ss", "Ljava/util/SortedSet;").await?; - jvm.invoke_virtual(&set, "last", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&set, &set.class_definition().name(), "last", "()Ljava/lang/Object;", ()) + .await } async fn sub_set( @@ -85,7 +88,13 @@ impl CollectionsUnmodifiableSortedSet { ) -> Result> { let set: ClassInstanceRef = jvm.get_field(&this, "ss", "Ljava/util/SortedSet;").await?; let range: ClassInstanceRef = jvm - .invoke_virtual(&set, "subSet", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedSet;", (from, to)) + .invoke_virtual( + &set, + &set.class_definition().name(), + "subSet", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedSet;", + (from, to), + ) .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableSortedSet", "(Ljava/util/SortedSet;)V", (range,)) @@ -101,7 +110,13 @@ impl CollectionsUnmodifiableSortedSet { ) -> Result> { let set: ClassInstanceRef = jvm.get_field(&this, "ss", "Ljava/util/SortedSet;").await?; let range: ClassInstanceRef = jvm - .invoke_virtual(&set, "headSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (to,)) + .invoke_virtual( + &set, + &set.class_definition().name(), + "headSet", + "(Ljava/lang/Object;)Ljava/util/SortedSet;", + (to,), + ) .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableSortedSet", "(Ljava/util/SortedSet;)V", (range,)) @@ -117,7 +132,13 @@ impl CollectionsUnmodifiableSortedSet { ) -> Result> { let set: ClassInstanceRef = jvm.get_field(&this, "ss", "Ljava/util/SortedSet;").await?; let range: ClassInstanceRef = jvm - .invoke_virtual(&set, "tailSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (from,)) + .invoke_virtual( + &set, + &set.class_definition().name(), + "tailSet", + "(Ljava/lang/Object;)Ljava/util/SortedSet;", + (from,), + ) .await?; Ok(jvm .new_class("java/util/Collections$UnmodifiableSortedSet", "(Ljava/util/SortedSet;)V", (range,)) diff --git a/java_runtime/src/classes/java/util/formatter.rs b/java_runtime/src/classes/java/util/formatter.rs index 7d5bad6d..f3648285 100644 --- a/java_runtime/src/classes/java/util/formatter.rs +++ b/java_runtime/src/classes/java/util/formatter.rs @@ -398,7 +398,9 @@ impl Formatter { } async fn locale(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "out", "()Ljava/lang/Appendable;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/Formatter", "out", "()Ljava/lang/Appendable;", ()) + .await?; jvm.get_field(&this, "l", "Ljava/util/Locale;").await } @@ -413,16 +415,24 @@ impl Formatter { } async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let appendable: ClassInstanceRef = jvm.invoke_virtual(&this, "out", "()Ljava/lang/Appendable;", ()).await?; - jvm.invoke_virtual(&appendable, "toString", "()Ljava/lang/String;", ()).await + let appendable: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/Formatter", "out", "()Ljava/lang/Appendable;", ()) + .await?; + jvm.invoke_virtual(&appendable, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn flush(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result<()> { - let appendable: ClassInstanceRef = jvm.invoke_virtual(&this, "out", "()Ljava/lang/Appendable;", ()).await?; + let appendable: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/Formatter", "out", "()Ljava/lang/Appendable;", ()) + .await?; if !jvm.is_instance(&**appendable, "java/io/Flushable") { return Ok(()); } - match jvm.invoke_virtual(&appendable, "flush", "()V", ()).await { + match jvm + .invoke_virtual(&appendable, &appendable.class_definition().name(), "flush", "()V", ()) + .await + { Ok(()) => Ok(()), Err(JavaError::JavaException(exception)) if jvm.is_instance(&*exception, "java/io/IOException") => { jvm.put_field( @@ -443,7 +453,8 @@ impl Formatter { return Ok(()); } let result = if jvm.is_instance(&**appendable, "java/io/Closeable") { - jvm.invoke_virtual(&appendable, "close", "()V", ()).await + jvm.invoke_virtual(&appendable, &appendable.class_definition().name(), "close", "()V", ()) + .await } else { Ok(()) }; @@ -472,10 +483,18 @@ impl Formatter { if characters.is_empty() { return Ok(()); } - let appendable: ClassInstanceRef = jvm.invoke_virtual(this, "out", "()Ljava/lang/Appendable;", ()).await?; + let appendable: ClassInstanceRef = jvm + .invoke_virtual(this, "java/util/Formatter", "out", "()Ljava/lang/Appendable;", ()) + .await?; let text: ClassInstanceRef = JavaLangString::from_utf16(jvm, characters).await?.into(); match jvm - .invoke_virtual::<_, ClassInstanceRef>(&appendable, "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;", (text,)) + .invoke_virtual::<_, ClassInstanceRef>( + &appendable, + &appendable.class_definition().name(), + "append", + "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;", + (text,), + ) .await { Ok(_) => Ok(()), @@ -502,6 +521,7 @@ impl Formatter { let locale: ClassInstanceRef = jvm.get_field(&this, "l", "Ljava/util/Locale;").await?; jvm.invoke_virtual( &this, + "java/util/Formatter", "format", "(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (locale, format, arguments), @@ -517,7 +537,9 @@ impl Formatter { format: ClassInstanceRef, arguments: ClassInstanceRef>, ) -> Result> { - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "out", "()Ljava/lang/Appendable;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/Formatter", "out", "()Ljava/lang/Appendable;", ()) + .await?; if format.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "format is null").await); } @@ -910,7 +932,9 @@ impl Formatter { { formatter.clone() } else { - let appendable: ClassInstanceRef = jvm.invoke_virtual(formatter, "out", "()Ljava/lang/Appendable;", ()).await?; + let appendable: ClassInstanceRef = jvm + .invoke_virtual(formatter, "java/util/Formatter", "out", "()Ljava/lang/Appendable;", ()) + .await?; jvm.new_class( "java/util/Formatter", "(Ljava/lang/Appendable;Ljava/util/Locale;)V", @@ -922,6 +946,7 @@ impl Formatter { let _: () = jvm .invoke_virtual( &argument, + &argument.class_definition().name(), "formatTo", "(Ljava/util/Formatter;III)V", ( @@ -948,7 +973,9 @@ impl Formatter { let mut text = if argument.is_null() { "null".encode_utf16().collect() } else { - let value: ClassInstanceRef = jvm.invoke_virtual(&argument, "toString", "()Ljava/lang/String;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&argument, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; JavaLangString::to_utf16(jvm, &value).await? }; if let Some(precision) = specifier.precision { @@ -963,7 +990,8 @@ impl Formatter { let value = if argument.is_null() { false } else if jvm.is_instance(&**argument, "java/lang/Boolean") { - jvm.invoke_virtual(&argument, "booleanValue", "()Z", ()).await? + jvm.invoke_virtual(&argument, &argument.class_definition().name(), "booleanValue", "()Z", ()) + .await? } else { true }; @@ -980,7 +1008,7 @@ impl Formatter { let mut text: Vec = if argument.is_null() { "null".encode_utf16().collect() } else { - let hash: i32 = jvm.invoke_virtual(&argument, "hashCode", "()I", ()).await?; + let hash: i32 = jvm.invoke_virtual(&argument, "java/lang/Object", "hashCode", "()I", ()).await?; format!("{:x}", hash as u32).encode_utf16().collect() }; if let Some(precision) = specifier.precision { @@ -997,12 +1025,14 @@ impl Formatter { return Ok(Some(Self::apply_width(jvm, text, specifier, ' ' as JavaChar).await?)); } let code_point = if jvm.is_instance(&**argument, "java/lang/Character") { - jvm.invoke_virtual::<_, JavaChar>(&argument, "charValue", "()C", ()).await? as i32 + jvm.invoke_virtual::<_, JavaChar>(&argument, &argument.class_definition().name(), "charValue", "()C", ()) + .await? as i32 } else if jvm.is_instance(&**argument, "java/lang/Byte") || jvm.is_instance(&**argument, "java/lang/Short") || jvm.is_instance(&**argument, "java/lang/Integer") { - jvm.invoke_virtual(&argument, "intValue", "()I", ()).await? + jvm.invoke_virtual(&argument, &argument.class_definition().name(), "intValue", "()I", ()) + .await? } else { return Err(Self::illegal_conversion(jvm, specifier, &argument).await?); }; @@ -1087,7 +1117,9 @@ impl Formatter { if conversion != 'd' { Self::validate_flags(jvm, specifier, "-#0").await?; } - let value: i64 = jvm.invoke_virtual(&argument, "longValue", "()J", ()).await?; + let value: i64 = jvm + .invoke_virtual(&argument, &argument.class_definition().name(), "longValue", "()J", ()) + .await?; let (digits, negative, prefix) = if conversion == 'd' { (value.unsigned_abs().to_string(), value < 0, RustString::new()) } else { @@ -1143,7 +1175,9 @@ impl Formatter { if !jvm.is_instance(&**argument, "java/lang/Float") && !jvm.is_instance(&**argument, "java/lang/Double") { return Err(Self::illegal_conversion(jvm, specifier, &argument).await?); } - let value: f64 = jvm.invoke_virtual(&argument, "doubleValue", "()D", ()).await?; + let value: f64 = jvm + .invoke_virtual(&argument, &argument.class_definition().name(), "doubleValue", "()D", ()) + .await?; let negative = value.is_sign_negative() && !value.is_nan(); let magnitude = libm::fabs(value); let precision = specifier.precision.unwrap_or(6); diff --git a/java_runtime/src/classes/java/util/gregorian_calendar.rs b/java_runtime/src/classes/java/util/gregorian_calendar.rs index d525d577..5c5f799f 100644 --- a/java_runtime/src/classes/java/util/gregorian_calendar.rs +++ b/java_runtime/src/classes/java/util/gregorian_calendar.rs @@ -3,6 +3,7 @@ use alloc::{vec, vec::Vec}; use chrono::{DateTime, Datelike, TimeZone as ChronoTimeZone, Timelike, Utc}; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::util::TimeZone}; @@ -17,13 +18,13 @@ impl GregorianCalendar { parent_class: Some("java/util/Calendar"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/util/TimeZone;)V", Self::init_with_time_zone, Default::default()), - JavaMethodProto::new("computeTime", "()V", Self::compute_time, Default::default()), - JavaMethodProto::new("computeFields", "()V", Self::compute_fields, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/util/TimeZone;)V", Self::init_with_time_zone, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("computeTime", "()V", Self::compute_time, MethodAccessFlags::PROTECTED), + JavaMethodProto::new("computeFields", "()V", Self::compute_fields, MethodAccessFlags::PROTECTED), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -32,7 +33,7 @@ impl GregorianCalendar { let _: () = jvm.invoke_special(&this, "java/util/Calendar", "", "()V", ()).await?; jvm.put_field(&mut this, "time", "J", context.now() as i64).await?; - jvm.invoke_virtual(&this, "computeFields", "()V", ()).await + jvm.invoke_virtual(&this, "java/util/GregorianCalendar", "computeFields", "()V", ()).await } async fn init_with_time_zone( @@ -50,7 +51,7 @@ impl GregorianCalendar { let _: () = jvm.invoke_special(&this, "java/util/Calendar", "", "()V", ()).await?; jvm.put_field(&mut this, "timeZone", "Ljava/util/TimeZone;", time_zone).await?; jvm.put_field(&mut this, "time", "J", context.now() as i64).await?; - jvm.invoke_virtual(&this, "computeFields", "()V", ()).await + jvm.invoke_virtual(&this, "java/util/GregorianCalendar", "computeFields", "()V", ()).await } async fn compute_time(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result<()> { @@ -107,7 +108,7 @@ impl GregorianCalendar { let time: i64 = jvm.get_field(&this, "time", "J").await?; let time_zone: ClassInstanceRef = jvm.get_field(&this, "timeZone", "Ljava/util/TimeZone;").await?; - let zone_offset: i32 = jvm.invoke_virtual(&time_zone, "getRawOffset", "()I", ()).await?; + let zone_offset: i32 = jvm.invoke_virtual(&time_zone, "java/util/TimeZone", "getRawOffset", "()I", ()).await?; let Some(adjusted_time) = time.checked_add(zone_offset as i64) else { return Err(jvm.exception("java/lang/IllegalArgumentException", "calendar time out of range").await); }; diff --git a/java_runtime/src/classes/java/util/hash_map.rs b/java_runtime/src/classes/java/util/hash_map.rs index 177e9626..0d7fdfec 100644 --- a/java_runtime/src/classes/java/util/hash_map.rs +++ b/java_runtime/src/classes/java/util/hash_map.rs @@ -163,7 +163,7 @@ impl HashMap { .await?; jvm.put_field(&mut this, "loadFactor", "F", load_factor).await?; jvm.put_field(&mut this, "modCount", "I", 0).await?; - let _: () = jvm.invoke_virtual(&this, "initializeMap", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&this, "java/util/HashMap", "initializeMap", "()V", ()).await?; Ok(()) } @@ -174,17 +174,25 @@ impl HashMap { if map.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "map").await); } - let size: i32 = jvm.invoke_virtual(&map, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&map, &map.class_definition().name(), "size", "()I", ()).await?; let capacity = size.saturating_mul(2).max(DEFAULT_INITIAL_CAPACITY); let _: () = jvm .invoke_special(&this, "java/util/HashMap", "", "(IF)V", (capacity, DEFAULT_LOAD_FACTOR)) .await?; - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - let entries: ClassInstanceRef> = jvm.invoke_virtual(&entry_set, "toArray", "()[Ljava/lang/Object;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let entries: ClassInstanceRef> = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let count = jvm.array_length(&entries).await?; for entry in jvm.load_array::>(&entries, 0, count).await? { - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; Self::put_for_create(jvm, &mut this, key, value).await?; } @@ -268,7 +276,9 @@ impl HashMap { if Self::keys_equal(jvm, &key, &entry_key).await? { let old_value: ClassInstanceRef = jvm.get_field(&entry, "value", "Ljava/lang/Object;").await?; jvm.put_field(&mut entry, "value", "Ljava/lang/Object;", value).await?; - let _: () = jvm.invoke_virtual(&entry, "onAccess", "(Ljava/util/HashMap;)V", (this.clone(),)).await?; + let _: () = jvm + .invoke_virtual(&entry, "java/util/HashMap$Entry", "onAccess", "(Ljava/util/HashMap;)V", (this.clone(),)) + .await?; return Ok(old_value); } } @@ -279,6 +289,7 @@ impl HashMap { let _: () = jvm .invoke_virtual( &this, + "java/util/HashMap", "insertNewEntry", "(ILjava/lang/Object;Ljava/lang/Object;I)V", (key_hash, key, value, bucket_index as i32), @@ -326,7 +337,9 @@ impl HashMap { } let old_value: ClassInstanceRef = jvm.get_field(&entry, "value", "Ljava/lang/Object;").await?; - let _: () = jvm.invoke_virtual(&entry, "onRemoval", "(Ljava/util/HashMap;)V", (this.clone(),)).await?; + let _: () = jvm + .invoke_virtual(&entry, "java/util/HashMap$Entry", "onRemoval", "(Ljava/util/HashMap;)V", (this.clone(),)) + .await?; let null_entry: ClassInstanceRef = None.into(); jvm.put_field(&mut entry, "next", "Ljava/util/HashMap$Entry;", null_entry).await?; @@ -405,6 +418,7 @@ impl HashMap { let _: () = jvm .invoke_virtual( &this, + "java/util/HashMap", "storeNewEntry", "(ILjava/lang/Object;Ljava/lang/Object;I)V", (hash, key, value, bucket_index), @@ -486,6 +500,7 @@ impl HashMap { let bucket_index = Self::bucket_index(hash, jvm.array_length(&table).await?); jvm.invoke_virtual( this, + "java/util/HashMap", "storeNewEntry", "(ILjava/lang/Object;Ljava/lang/Object;I)V", (hash, key, value, bucket_index as i32), @@ -551,7 +566,8 @@ impl HashMap { return Ok(false); } - jvm.invoke_virtual(left, "equals", "(Ljava/lang/Object;)Z", (right.clone(),)).await + jvm.invoke_virtual(left, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) + .await } async fn keys_equal(jvm: &Jvm, query_key: &ClassInstanceRef, stored_key: &ClassInstanceRef) -> Result { @@ -563,7 +579,7 @@ impl HashMap { return Ok(false); } - jvm.invoke_virtual(query_key, "equals", "(Ljava/lang/Object;)Z", (stored_key.clone(),)) + jvm.invoke_virtual(query_key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (stored_key.clone(),)) .await } @@ -572,7 +588,7 @@ impl HashMap { return Ok(0); } - jvm.invoke_virtual(value, "hashCode", "()I", ()).await + jvm.invoke_virtual(value, "java/lang/Object", "hashCode", "()I", ()).await } fn bucket_index(hash: i32, table_len: usize) -> usize { diff --git a/java_runtime/src/classes/java/util/hash_map_entry.rs b/java_runtime/src/classes/java/util/hash_map_entry.rs index 4ec0e4ea..071db707 100644 --- a/java_runtime/src/classes/java/util/hash_map_entry.rs +++ b/java_runtime/src/classes/java/util/hash_map_entry.rs @@ -100,22 +100,28 @@ impl HashMapEntry { } let key: ClassInstanceRef = jvm.get_field(&this, "key", "Ljava/lang/Object;").await?; - let other_key: ClassInstanceRef = jvm.invoke_virtual(&other, "getKey", "()Ljava/lang/Object;", ()).await?; + let other_key: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; let keys_equal = if key.is_null() { other_key.is_null() } else { - jvm.invoke_virtual(&key, "equals", "(Ljava/lang/Object;)Z", (other_key,)).await? + jvm.invoke_virtual(&key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_key,)) + .await? }; if !keys_equal { return Ok(false); } let value: ClassInstanceRef = jvm.get_field(&this, "value", "Ljava/lang/Object;").await?; - let other_value: ClassInstanceRef = jvm.invoke_virtual(&other, "getValue", "()Ljava/lang/Object;", ()).await?; + let other_value: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; if value.is_null() { Ok(other_value.is_null()) } else { - jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (other_value,)).await + jvm.invoke_virtual(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_value,)) + .await } } @@ -125,12 +131,12 @@ impl HashMapEntry { let key_hash = if key.is_null() { 0 } else { - jvm.invoke_virtual(&key, "hashCode", "()I", ()).await? + jvm.invoke_virtual(&key, "java/lang/Object", "hashCode", "()I", ()).await? }; let value_hash = if value.is_null() { 0 } else { - jvm.invoke_virtual(&value, "hashCode", "()I", ()).await? + jvm.invoke_virtual(&value, "java/lang/Object", "hashCode", "()I", ()).await? }; Ok(key_hash ^ value_hash) } diff --git a/java_runtime/src/classes/java/util/hash_map_entry_set.rs b/java_runtime/src/classes/java/util/hash_map_entry_set.rs index 4f51083e..28b8c826 100644 --- a/java_runtime/src/classes/java/util/hash_map_entry_set.rs +++ b/java_runtime/src/classes/java/util/hash_map_entry_set.rs @@ -45,7 +45,7 @@ impl HashMapEntrySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "size", "()I", ()).await } async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -53,7 +53,7 @@ impl HashMapEntrySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "isEmpty", "()Z", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, candidate: ClassInstanceRef) -> Result { @@ -64,7 +64,9 @@ impl HashMapEntrySet { } let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - let candidate_key: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getKey", "()Ljava/lang/Object;", ()).await?; + let candidate_key: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; let entry = HashMap::find_entry(jvm, &map, &candidate_key).await?; if entry.is_null() { @@ -76,7 +78,9 @@ impl HashMapEntrySet { return Ok(false); } - let candidate_value: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getValue", "()Ljava/lang/Object;", ()).await?; + let candidate_value: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; let entry_value: ClassInstanceRef = jvm.get_field(&entry, "value", "Ljava/lang/Object;").await?; Self::object_equals(jvm, &entry_value, &candidate_value).await @@ -90,7 +94,9 @@ impl HashMapEntrySet { } let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - let candidate_key: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getKey", "()Ljava/lang/Object;", ()).await?; + let candidate_key: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; let entry = HashMap::find_entry(jvm, &map, &candidate_key).await?; if entry.is_null() { return Ok(false); @@ -101,14 +107,22 @@ impl HashMapEntrySet { return Ok(false); } - let candidate_value: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getValue", "()Ljava/lang/Object;", ()).await?; + let candidate_value: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; let entry_value: ClassInstanceRef = jvm.get_field(&entry, "value", "Ljava/lang/Object;").await?; if !Self::object_equals(jvm, &entry_value, &candidate_value).await? { return Ok(false); } let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (candidate_key,)) + .invoke_virtual( + &map, + "java/util/HashMap", + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (candidate_key,), + ) .await?; Ok(true) @@ -119,7 +133,7 @@ impl HashMapEntrySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { @@ -127,7 +141,8 @@ impl HashMapEntrySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "entryIterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "entryIterator", "()Ljava/util/Iterator;", ()) + .await } async fn object_equals(jvm: &Jvm, left: &ClassInstanceRef, right: &ClassInstanceRef) -> Result { @@ -135,6 +150,7 @@ impl HashMapEntrySet { return Ok(right.is_null()); } - jvm.invoke_virtual(left, "equals", "(Ljava/lang/Object;)Z", (right.clone(),)).await + jvm.invoke_virtual(left, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) + .await } } diff --git a/java_runtime/src/classes/java/util/hash_map_key_set.rs b/java_runtime/src/classes/java/util/hash_map_key_set.rs index cc083a2a..bb29d006 100644 --- a/java_runtime/src/classes/java/util/hash_map_key_set.rs +++ b/java_runtime/src/classes/java/util/hash_map_key_set.rs @@ -44,7 +44,7 @@ impl HashMapKeySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "size", "()I", ()).await } async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -52,7 +52,7 @@ impl HashMapKeySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "isEmpty", "()Z", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, key: ClassInstanceRef) -> Result { @@ -60,20 +60,23 @@ impl HashMapKeySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (key,)).await + jvm.invoke_virtual(&map, "java/util/HashMap", "containsKey", "(Ljava/lang/Object;)Z", (key,)) + .await } async fn remove(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, key: ClassInstanceRef) -> Result { tracing::debug!("java.util.HashMap$KeySet::remove({this:?}, {key:?})"); let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - let contains: bool = jvm.invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)).await?; + let contains: bool = jvm + .invoke_virtual(&map, "java/util/HashMap", "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)) + .await?; if !contains { return Ok(false); } let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual(&map, "java/util/HashMap", "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) .await?; Ok(true) @@ -84,7 +87,7 @@ impl HashMapKeySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { @@ -92,6 +95,7 @@ impl HashMapKeySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "keyIterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "keyIterator", "()Ljava/util/Iterator;", ()) + .await } } diff --git a/java_runtime/src/classes/java/util/hash_map_values.rs b/java_runtime/src/classes/java/util/hash_map_values.rs index 323811d6..bf9c9de3 100644 --- a/java_runtime/src/classes/java/util/hash_map_values.rs +++ b/java_runtime/src/classes/java/util/hash_map_values.rs @@ -45,7 +45,7 @@ impl HashMapValues { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "size", "()I", ()).await } async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -53,7 +53,7 @@ impl HashMapValues { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "isEmpty", "()Z", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result { @@ -61,28 +61,41 @@ impl HashMapValues { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "containsValue", "(Ljava/lang/Object;)Z", (value,)).await + jvm.invoke_virtual(&map, "java/util/HashMap", "containsValue", "(Ljava/lang/Object;)Z", (value,)) + .await } async fn remove(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result { tracing::debug!("java.util.HashMap$Values::remove({this:?}, {value:?})"); let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&map, "entryIterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let entry_value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&map, "java/util/HashMap", "entryIterator", "()Ljava/util/Iterator;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let entry_value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; let equal = if value.is_null() { entry_value.is_null() } else if entry_value.is_null() { false } else { - jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (entry_value,)).await? + jvm.invoke_virtual(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (entry_value,)) + .await? }; if equal { - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual(&map, "java/util/HashMap", "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) .await?; return Ok(true); } @@ -96,7 +109,7 @@ impl HashMapValues { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { @@ -104,6 +117,7 @@ impl HashMapValues { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "valueIterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "valueIterator", "()Ljava/util/Iterator;", ()) + .await } } diff --git a/java_runtime/src/classes/java/util/hash_set.rs b/java_runtime/src/classes/java/util/hash_set.rs index 508afabd..709e3cc0 100644 --- a/java_runtime/src/classes/java/util/hash_set.rs +++ b/java_runtime/src/classes/java/util/hash_set.rs @@ -80,10 +80,14 @@ impl HashSet { if collection.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - let size: i32 = jvm.invoke_virtual(&collection, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&collection, &collection.class_definition().name(), "size", "()I", ()) + .await?; let capacity = size.saturating_mul(2).max(DEFAULT_INITIAL_CAPACITY); let _: () = jvm.invoke_special(&this, "java/util/HashSet", "", "(I)V", (capacity,)).await?; - let _: bool = jvm.invoke_virtual(&this, "addAll", "(Ljava/util/Collection;)Z", (collection,)).await?; + let _: bool = jvm + .invoke_virtual(&this, "java/util/HashSet", "addAll", "(Ljava/util/Collection;)Z", (collection,)) + .await?; Ok(()) } @@ -96,6 +100,7 @@ impl HashSet { let old: ClassInstanceRef = jvm .invoke_virtual( &map, + "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (element, present), @@ -110,7 +115,7 @@ impl HashSet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; let old: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (element,)) + .invoke_virtual(&map, "java/util/HashMap", "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (element,)) .await?; Ok(!old.is_null()) @@ -121,7 +126,8 @@ impl HashSet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (element,)).await + jvm.invoke_virtual(&map, "java/util/HashMap", "containsKey", "(Ljava/lang/Object;)Z", (element,)) + .await } async fn size(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -129,7 +135,7 @@ impl HashSet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "size", "()I", ()).await } async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -137,7 +143,7 @@ impl HashSet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "isEmpty", "()Z", ()).await } async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { @@ -145,7 +151,7 @@ impl HashSet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { @@ -153,7 +159,8 @@ impl HashSet { let key_set = Self::key_set(jvm, &this).await?; - jvm.invoke_virtual(&key_set, "iterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&key_set, &key_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await } async fn to_array(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result>> { @@ -161,12 +168,13 @@ impl HashSet { let key_set = Self::key_set(jvm, &this).await?; - jvm.invoke_virtual(&key_set, "toArray", "()[Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&key_set, &key_set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await } async fn key_set(jvm: &Jvm, this: &ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(this, "map", "Ljava/util/HashMap;").await?; - jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await + jvm.invoke_virtual(&map, "java/util/HashMap", "keySet", "()Ljava/util/Set;", ()).await } } diff --git a/java_runtime/src/classes/java/util/hashtable.rs b/java_runtime/src/classes/java/util/hashtable.rs index 07ebe21a..f59fa358 100644 --- a/java_runtime/src/classes/java/util/hashtable.rs +++ b/java_runtime/src/classes/java/util/hashtable.rs @@ -24,21 +24,46 @@ impl Hashtable { parent_class: Some("java/util/Dictionary"), interfaces: vec!["java/util/Map", "java/lang/Cloneable", "java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(I)V", Self::init_with_capacity, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(I)V", Self::init_with_capacity, MethodAccessFlags::PUBLIC), JavaMethodProto::new("", "(Ljava/util/Map;)V", Self::init_from_map, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("size", "()I", Self::size, Default::default()), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), - JavaMethodProto::new("containsKey", "(Ljava/lang/Object;)Z", Self::contains_key, Default::default()), - JavaMethodProto::new("containsValue", "(Ljava/lang/Object;)Z", Self::contains_value, Default::default()), - JavaMethodProto::new("keys", "()Ljava/util/Enumeration;", Self::keys, Default::default()), - JavaMethodProto::new("elements", "()Ljava/util/Enumeration;", Self::elements, Default::default()), + JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED), + JavaMethodProto::new( + "isEmpty", + "()Z", + Self::is_empty, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "contains", + "(Ljava/lang/Object;)Z", + Self::contains, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "containsKey", + "(Ljava/lang/Object;)Z", + Self::contains_key, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new("containsValue", "(Ljava/lang/Object;)Z", Self::contains_value, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "keys", + "()Ljava/util/Enumeration;", + Self::keys, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "elements", + "()Ljava/util/Enumeration;", + Self::elements, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), JavaMethodProto::new( "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", Self::put, - Default::default(), + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), JavaMethodProto::new( "putAll", @@ -46,12 +71,22 @@ impl Hashtable { Self::put_all, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), - JavaMethodProto::new("get", "(Ljava/lang/Object;)Ljava/lang/Object;", Self::get, Default::default()), - JavaMethodProto::new("remove", "(Ljava/lang/Object;)Ljava/lang/Object;", Self::remove, Default::default()), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("keySet", "()Ljava/util/Set;", Self::key_set, Default::default()), - JavaMethodProto::new("values", "()Ljava/util/Collection;", Self::values, Default::default()), - JavaMethodProto::new("entrySet", "()Ljava/util/Set;", Self::entry_set, Default::default()), + JavaMethodProto::new( + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + Self::get, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + Self::remove, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED), + JavaMethodProto::new("keySet", "()Ljava/util/Set;", Self::key_set, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("values", "()Ljava/util/Collection;", Self::values, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("entrySet", "()Ljava/util/Set;", Self::entry_set, MethodAccessFlags::PUBLIC), JavaMethodProto::new("rehash", "()V", Self::rehash, MethodAccessFlags::PROTECTED), JavaMethodProto::new( "equals", @@ -65,7 +100,12 @@ impl Hashtable { Self::hash_code, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), - JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, Default::default()), + JavaMethodProto::new( + "toString", + "()Ljava/lang/String;", + Self::to_string, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), ], fields: vec![ JavaFieldProto::new("table", "[Ljava/util/Hashtable$Entry;", Default::default()), @@ -110,17 +150,20 @@ impl Hashtable { if map.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "map").await); } - let size: i32 = jvm.invoke_virtual(&map, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&map, &map.class_definition().name(), "size", "()I", ()).await?; let capacity = size.saturating_mul(2).max(DEFAULT_INITIAL_CAPACITY); let _: () = jvm.invoke_special(&this, "java/util/Hashtable", "", "(I)V", (capacity,)).await?; - let _: () = jvm.invoke_virtual(&this, "putAll", "(Ljava/util/Map;)V", (map,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/util/Hashtable", "putAll", "(Ljava/util/Map;)V", (map,)) + .await?; Ok(()) } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result { tracing::debug!("java.util.Hashtable::contains({this:?}, {value:?})"); - jvm.invoke_virtual(&this, "containsValue", "(Ljava/lang/Object;)Z", (value,)).await + jvm.invoke_virtual(&this, "java/util/Hashtable", "containsValue", "(Ljava/lang/Object;)Z", (value,)) + .await } async fn keys(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { @@ -170,7 +213,9 @@ impl Hashtable { let entry_hash: i32 = jvm.get_field(&entry, "hash", "I").await?; if entry_hash == key_hash { let entry_key: ClassInstanceRef = jvm.get_field(&entry, "key", "Ljava/lang/Object;").await?; - let equals: bool = jvm.invoke_virtual(&entry_key, "equals", "(Ljava/lang/Object;)Z", (key.clone(),)).await?; + let equals: bool = jvm + .invoke_virtual(&entry_key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (key.clone(),)) + .await?; if equals { return Ok(true); } @@ -218,7 +263,9 @@ impl Hashtable { let entry_hash: i32 = jvm.get_field(&entry, "hash", "I").await?; if entry_hash == key_hash { let entry_key: ClassInstanceRef = jvm.get_field(&entry, "key", "Ljava/lang/Object;").await?; - let equals: bool = jvm.invoke_virtual(&entry_key, "equals", "(Ljava/lang/Object;)Z", (key.clone(),)).await?; + let equals: bool = jvm + .invoke_virtual(&entry_key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (key.clone(),)) + .await?; if equals { return jvm.get_field(&entry, "value", "Ljava/lang/Object;").await; } @@ -249,7 +296,9 @@ impl Hashtable { let entry_hash: i32 = jvm.get_field(&entry, "hash", "I").await?; if entry_hash == key_hash { let entry_key: ClassInstanceRef = jvm.get_field(&entry, "key", "Ljava/lang/Object;").await?; - let equals: bool = jvm.invoke_virtual(&entry_key, "equals", "(Ljava/lang/Object;)Z", (key.clone(),)).await?; + let equals: bool = jvm + .invoke_virtual(&entry_key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (key.clone(),)) + .await?; if equals { let next: ClassInstanceRef = jvm.get_field(&entry, "next", "Ljava/util/Hashtable$Entry;").await?; if prev.is_null() { @@ -294,7 +343,9 @@ impl Hashtable { let entry_hash: i32 = jvm.get_field(&entry, "hash", "I").await?; if entry_hash == key_hash { let entry_key: ClassInstanceRef = jvm.get_field(&entry, "key", "Ljava/lang/Object;").await?; - let equals: bool = jvm.invoke_virtual(&entry_key, "equals", "(Ljava/lang/Object;)Z", (key.clone(),)).await?; + let equals: bool = jvm + .invoke_virtual(&entry_key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (key.clone(),)) + .await?; if equals { let old_value: ClassInstanceRef = jvm.get_field(&entry, "value", "Ljava/lang/Object;").await?; jvm.put_field(&mut entry, "value", "Ljava/lang/Object;", value).await?; @@ -349,13 +400,21 @@ impl Hashtable { return Ok(()); } - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - let entries: ClassInstanceRef> = jvm.invoke_virtual(&entry_set, "toArray", "()[Ljava/lang/Object;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let entries: ClassInstanceRef> = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let count = jvm.array_length(&entries).await?; let mut validated = Vec::with_capacity(count); for entry in jvm.load_array::>(&entries, 0, count).await? { - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; if key.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "Hashtable key is null").await); } @@ -367,7 +426,13 @@ impl Hashtable { for (key, value) in validated { let _: ClassInstanceRef = jvm - .invoke_virtual(&this, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &this, + "java/util/Hashtable", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } @@ -439,7 +504,9 @@ impl Hashtable { let entry_hash: i32 = jvm.get_field(&entry, "hash", "I").await?; if entry_hash == key_hash { let entry_key: ClassInstanceRef = jvm.get_field(&entry, "key", "Ljava/lang/Object;").await?; - let equals: bool = jvm.invoke_virtual(&entry_key, "equals", "(Ljava/lang/Object;)Z", (key.clone(),)).await?; + let equals: bool = jvm + .invoke_virtual(&entry_key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (key.clone(),)) + .await?; if equals { return Ok(entry); } @@ -496,7 +563,7 @@ impl Hashtable { } let count: i32 = jvm.get_field(&this, "count", "I").await?; - let other_size: i32 = jvm.invoke_virtual(&other, "size", "()I", ()).await?; + let other_size: i32 = jvm.invoke_virtual(&other, &other.class_definition().name(), "size", "()I", ()).await?; if count != other_size { return Ok(false); } @@ -510,18 +577,24 @@ impl Hashtable { let key: ClassInstanceRef = jvm.get_field(&entry, "key", "Ljava/lang/Object;").await?; let value: ClassInstanceRef = jvm.get_field(&entry, "value", "Ljava/lang/Object;").await?; let other_value: ClassInstanceRef = jvm - .invoke_virtual(&other, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) + .invoke_virtual( + &other, + &other.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),), + ) .await?; if value.is_null() { if !other_value.is_null() || !jvm - .invoke_virtual::<_, bool>(&other, "containsKey", "(Ljava/lang/Object;)Z", (key,)) + .invoke_virtual::<_, bool>(&other, &other.class_definition().name(), "containsKey", "(Ljava/lang/Object;)Z", (key,)) .await? { return Ok(false); } } else if !jvm - .invoke_virtual::<_, bool>(&value, "equals", "(Ljava/lang/Object;)Z", (other_value,)) + .invoke_virtual::<_, bool>(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_value,)) .await? { return Ok(false); @@ -562,7 +635,7 @@ impl Hashtable { for bucket_index in 0..table_len { let mut entry = Self::load_bucket(jvm, &table, bucket_index).await?; while !entry.is_null() { - hash = hash.wrapping_add(jvm.invoke_virtual::<_, i32>(&entry, "hashCode", "()I", ()).await?); + hash = hash.wrapping_add(jvm.invoke_virtual::<_, i32>(&entry, "java/lang/Object", "hashCode", "()I", ()).await?); entry = jvm.get_field(&entry, "next", "Ljava/util/Hashtable$Entry;").await?; } } @@ -591,7 +664,9 @@ impl Hashtable { if key.instance.as_ref().unwrap().equals(&**this)? { result.push_str("(this Map)"); } else { - let text: ClassInstanceRef = jvm.invoke_virtual(&key, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&key, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; result.push_str(&JavaLangString::to_rust_string(jvm, &text).await?); } result.push('='); @@ -600,7 +675,9 @@ impl Hashtable { if value.instance.as_ref().unwrap().equals(&**this)? { result.push_str("(this Map)"); } else { - let text: ClassInstanceRef = jvm.invoke_virtual(&value, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&value, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; result.push_str(&JavaLangString::to_rust_string(jvm, &text).await?); } } @@ -622,7 +699,7 @@ impl Hashtable { return Err(jvm.exception("java/lang/NullPointerException", "Hashtable key is null").await); } - jvm.invoke_virtual(key, "hashCode", "()I", ()).await + jvm.invoke_virtual(key, "java/lang/Object", "hashCode", "()I", ()).await } async fn object_equals(jvm: &Jvm, left: &ClassInstanceRef, right: &ClassInstanceRef) -> Result { @@ -634,7 +711,8 @@ impl Hashtable { return Ok(false); } - jvm.invoke_virtual(left, "equals", "(Ljava/lang/Object;)Z", (right.clone(),)).await + jvm.invoke_virtual(left, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) + .await } async fn snapshot_entries(jvm: &Jvm, this: &ClassInstanceRef, kind: SnapshotKind) -> Result>> { diff --git a/java_runtime/src/classes/java/util/hashtable_entry.rs b/java_runtime/src/classes/java/util/hashtable_entry.rs index 6aa7be20..9588f6a7 100644 --- a/java_runtime/src/classes/java/util/hashtable_entry.rs +++ b/java_runtime/src/classes/java/util/hashtable_entry.rs @@ -95,22 +95,28 @@ impl HashtableEntry { } let key: ClassInstanceRef = jvm.get_field(&this, "key", "Ljava/lang/Object;").await?; - let other_key: ClassInstanceRef = jvm.invoke_virtual(&other, "getKey", "()Ljava/lang/Object;", ()).await?; + let other_key: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; let keys_equal = if key.is_null() { other_key.is_null() } else { - jvm.invoke_virtual(&key, "equals", "(Ljava/lang/Object;)Z", (other_key,)).await? + jvm.invoke_virtual(&key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_key,)) + .await? }; if !keys_equal { return Ok(false); } let value: ClassInstanceRef = jvm.get_field(&this, "value", "Ljava/lang/Object;").await?; - let other_value: ClassInstanceRef = jvm.invoke_virtual(&other, "getValue", "()Ljava/lang/Object;", ()).await?; + let other_value: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; if value.is_null() { Ok(other_value.is_null()) } else { - jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (other_value,)).await + jvm.invoke_virtual(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_value,)) + .await } } @@ -120,12 +126,12 @@ impl HashtableEntry { let key_hash = if key.is_null() { 0 } else { - jvm.invoke_virtual(&key, "hashCode", "()I", ()).await? + jvm.invoke_virtual(&key, "java/lang/Object", "hashCode", "()I", ()).await? }; let value_hash = if value.is_null() { 0 } else { - jvm.invoke_virtual(&value, "hashCode", "()I", ()).await? + jvm.invoke_virtual(&value, "java/lang/Object", "hashCode", "()I", ()).await? }; Ok(key_hash ^ value_hash) diff --git a/java_runtime/src/classes/java/util/hashtable_entry_set.rs b/java_runtime/src/classes/java/util/hashtable_entry_set.rs index 68e5e570..9dc76fbf 100644 --- a/java_runtime/src/classes/java/util/hashtable_entry_set.rs +++ b/java_runtime/src/classes/java/util/hashtable_entry_set.rs @@ -45,7 +45,7 @@ impl HashtableEntrySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "size", "()I", ()).await } async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -53,7 +53,7 @@ impl HashtableEntrySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "isEmpty", "()Z", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, candidate: ClassInstanceRef) -> Result { @@ -63,7 +63,9 @@ impl HashtableEntrySet { return Ok(false); } - let candidate_key: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getKey", "()Ljava/lang/Object;", ()).await?; + let candidate_key: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; if candidate_key.is_null() { return Ok(false); } @@ -74,7 +76,9 @@ impl HashtableEntrySet { return Ok(false); } - let candidate_value: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getValue", "()Ljava/lang/Object;", ()).await?; + let candidate_value: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; let entry_value: ClassInstanceRef = jvm.get_field(&entry, "value", "Ljava/lang/Object;").await?; Self::object_equals(jvm, &entry_value, &candidate_value).await @@ -87,7 +91,9 @@ impl HashtableEntrySet { return Ok(false); } - let candidate_key: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getKey", "()Ljava/lang/Object;", ()).await?; + let candidate_key: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; if candidate_key.is_null() { return Ok(false); } @@ -96,14 +102,22 @@ impl HashtableEntrySet { if entry.is_null() { return Ok(false); } - let candidate_value: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getValue", "()Ljava/lang/Object;", ()).await?; + let candidate_value: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; let entry_value: ClassInstanceRef = jvm.get_field(&entry, "value", "Ljava/lang/Object;").await?; if !Self::object_equals(jvm, &entry_value, &candidate_value).await? { return Ok(false); } let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (candidate_key,)) + .invoke_virtual( + &map, + "java/util/Hashtable", + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (candidate_key,), + ) .await?; Ok(true) @@ -114,7 +128,7 @@ impl HashtableEntrySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { @@ -134,6 +148,7 @@ impl HashtableEntrySet { return Ok(right.is_null()); } - jvm.invoke_virtual(left, "equals", "(Ljava/lang/Object;)Z", (right.clone(),)).await + jvm.invoke_virtual(left, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) + .await } } diff --git a/java_runtime/src/classes/java/util/hashtable_key_set.rs b/java_runtime/src/classes/java/util/hashtable_key_set.rs index 6abfbf78..b76a0564 100644 --- a/java_runtime/src/classes/java/util/hashtable_key_set.rs +++ b/java_runtime/src/classes/java/util/hashtable_key_set.rs @@ -44,7 +44,7 @@ impl HashtableKeySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "size", "()I", ()).await } async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -52,7 +52,7 @@ impl HashtableKeySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "isEmpty", "()Z", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, key: ClassInstanceRef) -> Result { @@ -60,20 +60,23 @@ impl HashtableKeySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (key,)).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "containsKey", "(Ljava/lang/Object;)Z", (key,)) + .await } async fn remove(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, key: ClassInstanceRef) -> Result { tracing::debug!("java.util.Hashtable$KeySet::remove({this:?}, {key:?})"); let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - let contains: bool = jvm.invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)).await?; + let contains: bool = jvm + .invoke_virtual(&map, "java/util/Hashtable", "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)) + .await?; if !contains { return Ok(false); } let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual(&map, "java/util/Hashtable", "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) .await?; Ok(true) @@ -84,7 +87,7 @@ impl HashtableKeySet { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { diff --git a/java_runtime/src/classes/java/util/hashtable_values.rs b/java_runtime/src/classes/java/util/hashtable_values.rs index 4a39ed29..847a4252 100644 --- a/java_runtime/src/classes/java/util/hashtable_values.rs +++ b/java_runtime/src/classes/java/util/hashtable_values.rs @@ -45,7 +45,7 @@ impl HashtableValues { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "size", "()I", ()).await } async fn is_empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -53,7 +53,7 @@ impl HashtableValues { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "isEmpty", "()Z", ()).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "isEmpty", "()Z", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result { @@ -61,7 +61,8 @@ impl HashtableValues { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "containsValue", "(Ljava/lang/Object;)Z", (value,)).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "containsValue", "(Ljava/lang/Object;)Z", (value,)) + .await } async fn remove(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result { @@ -75,12 +76,18 @@ impl HashtableValues { let entries = Hashtable::entries_snapshot(jvm, &map).await?; let count = jvm.array_length(&entries).await?; for entry in jvm.load_array::>(&entries, 0, count).await? { - let entry_value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; - let equal: bool = jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (entry_value,)).await?; + let entry_value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; + let equal: bool = jvm + .invoke_virtual(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (entry_value,)) + .await?; if equal { - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual(&map, "java/util/Hashtable", "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) .await?; return Ok(true); } @@ -94,7 +101,7 @@ impl HashtableValues { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, "java/util/Hashtable", "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { diff --git a/java_runtime/src/classes/java/util/illegal_format_conversion_exception.rs b/java_runtime/src/classes/java/util/illegal_format_conversion_exception.rs index ed264573..d2904af7 100644 --- a/java_runtime/src/classes/java/util/illegal_format_conversion_exception.rs +++ b/java_runtime/src/classes/java/util/illegal_format_conversion_exception.rs @@ -63,7 +63,9 @@ impl IllegalFormatConversionException { async fn get_message(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let conversion: JavaChar = jvm.get_field(&this, "conversion", "C").await?; let argument_class: ClassInstanceRef = jvm.get_field(&this, "argumentClass", "Ljava/lang/Class;").await?; - let class_name: ClassInstanceRef = jvm.invoke_virtual(&argument_class, "getName", "()Ljava/lang/String;", ()).await?; + let class_name: ClassInstanceRef = jvm + .invoke_virtual(&argument_class, "java/lang/Class", "getName", "()Ljava/lang/String;", ()) + .await?; Ok(JavaLangString::from_rust_string( jvm, &format!( diff --git a/java_runtime/src/classes/java/util/jar/attributes.rs b/java_runtime/src/classes/java/util/jar/attributes.rs index 9f20ac97..081177f6 100644 --- a/java_runtime/src/classes/java/util/jar/attributes.rs +++ b/java_runtime/src/classes/java/util/jar/attributes.rs @@ -52,7 +52,13 @@ impl Attributes { // TODO we should store key in Attributes.Name type let map = jvm.get_field(&this, "map", "Ljava/util/Map;").await?; let old = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (name, value)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (name, value), + ) .await?; Ok(old) @@ -67,7 +73,15 @@ impl Attributes { tracing::debug!("java.util.jar.Attributes::getValue({this:?}, {name:?})"); let map = jvm.get_field(&this, "map", "Ljava/util/Map;").await?; - let value = jvm.invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (name,)).await?; + let value = jvm + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (name,), + ) + .await?; Ok(value) } diff --git a/java_runtime/src/classes/java/util/jar/jar_file.rs b/java_runtime/src/classes/java/util/jar/jar_file.rs index 7ed7c41b..3d53fae6 100644 --- a/java_runtime/src/classes/java/util/jar/jar_file.rs +++ b/java_runtime/src/classes/java/util/jar/jar_file.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -26,19 +27,19 @@ impl JarFile { parent_class: Some("java/util/zip/ZipFile"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/File;)V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_string, Default::default()), + JavaMethodProto::new("", "(Ljava/io/File;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_string, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "getJarEntry", "(Ljava/lang/String;)Ljava/util/jar/JarEntry;", Self::get_jar_entry, - Default::default(), + MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("entries", "()Ljava/util/Enumeration;", Self::entries, Default::default()), - JavaMethodProto::new("getManifest", "()Ljava/util/jar/Manifest;", Self::get_manifest, Default::default()), + JavaMethodProto::new("entries", "()Ljava/util/Enumeration;", Self::entries, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getManifest", "()Ljava/util/jar/Manifest;", Self::get_manifest, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -73,7 +74,13 @@ impl JarFile { tracing::debug!("java.util.jar.JarFile::getJarEntry({this:?}, {name:?})"); let zip_entry: ClassInstanceRef = jvm - .invoke_virtual(&this, "getEntry", "(Ljava/lang/String;)Ljava/util/zip/ZipEntry;", (name,)) + .invoke_virtual( + &this, + "java/util/jar/JarFile", + "getEntry", + "(Ljava/lang/String;)Ljava/util/zip/ZipEntry;", + (name,), + ) .await?; if zip_entry.is_null() { @@ -106,12 +113,19 @@ impl JarFile { let manifest_name = JavaLangString::from_rust_string(jvm, "META-INF/MANIFEST.MF").await?; let manifest_file: ClassInstanceRef = jvm - .invoke_virtual(&this, "getJarEntry", "(Ljava/lang/String;)Ljava/util/jar/JarEntry;", (manifest_name,)) + .invoke_virtual( + &this, + "java/util/jar/JarFile", + "getJarEntry", + "(Ljava/lang/String;)Ljava/util/jar/JarEntry;", + (manifest_name,), + ) .await?; let input_stream: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/util/jar/JarFile", "getInputStream", "(Ljava/util/zip/ZipEntry;)Ljava/io/InputStream;", (manifest_file,), diff --git a/java_runtime/src/classes/java/util/jar/jar_file_entries.rs b/java_runtime/src/classes/java/util/jar/jar_file_entries.rs index de218e5a..9da235dc 100644 --- a/java_runtime/src/classes/java/util/jar/jar_file_entries.rs +++ b/java_runtime/src/classes/java/util/jar/jar_file_entries.rs @@ -45,7 +45,8 @@ impl JarFileEntries { let entries = jvm.get_field(&this, "entries", "Ljava/util/zip/ZipFile$Entries;").await?; - jvm.invoke_virtual(&entries, "hasMoreElements", "()Z", ()).await + jvm.invoke_virtual(&entries, "java/util/zip/ZipFile$Entries", "hasMoreElements", "()Z", ()) + .await } async fn next_element(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { @@ -53,7 +54,9 @@ impl JarFileEntries { let entries = jvm.get_field(&this, "entries", "Ljava/util/zip/ZipFile$Entries;").await?; - let element: ClassInstanceRef = jvm.invoke_virtual(&entries, "nextElement", "()Ljava/lang/Object;", ()).await?; + let element: ClassInstanceRef = jvm + .invoke_virtual(&entries, "java/util/zip/ZipFile$Entries", "nextElement", "()Ljava/lang/Object;", ()) + .await?; let entry = jvm.new_class("java/util/jar/JarEntry", "(Ljava/util/zip/ZipEntry;)V", (element,)).await?; diff --git a/java_runtime/src/classes/java/util/jar/manifest.rs b/java_runtime/src/classes/java/util/jar/manifest.rs index ce6a0908..cea35b2d 100644 --- a/java_runtime/src/classes/java/util/jar/manifest.rs +++ b/java_runtime/src/classes/java/util/jar/manifest.rs @@ -1,6 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -18,17 +19,17 @@ impl Manifest { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Cloneable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/InputStream;)V", Self::init, Default::default()), - JavaMethodProto::new("read", "(Ljava/io/InputStream;)V", Self::read, Default::default()), + JavaMethodProto::new("", "(Ljava/io/InputStream;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "(Ljava/io/InputStream;)V", Self::read, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "getMainAttributes", "()Ljava/util/jar/Attributes;", Self::get_main_attributes, - Default::default(), + MethodAccessFlags::PUBLIC, ), ], fields: vec![JavaFieldProto::new("attrs", "Ljava/util/jar/Attributes;", Default::default())], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -37,7 +38,9 @@ impl Manifest { let _: () = jvm.invoke_special(&this, "java/lang/Object", "", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&this, "read", "(Ljava/io/InputStream;)V", (is,)).await?; + let _: () = jvm + .invoke_virtual(&this, "java/util/jar/Manifest", "read", "(Ljava/io/InputStream;)V", (is,)) + .await?; Ok(()) } @@ -53,7 +56,9 @@ impl Manifest { let buffered_reader = jvm.new_class("java/io/BufferedReader", "(Ljava/io/Reader;)V", (reader,)).await?; loop { - let line: ClassInstanceRef = jvm.invoke_virtual(&buffered_reader, "readLine", "()Ljava/lang/String;", ()).await?; + let line: ClassInstanceRef = jvm + .invoke_virtual(&buffered_reader, "java/io/BufferedReader", "readLine", "()Ljava/lang/String;", ()) + .await?; if line.is_null() { break; } @@ -72,6 +77,7 @@ impl Manifest { let _: ClassInstanceRef = jvm .invoke_virtual( &main_attributes, + "java/util/jar/Attributes", "putValue", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (key, value), diff --git a/java_runtime/src/classes/java/util/linked_hash_map.rs b/java_runtime/src/classes/java/util/linked_hash_map.rs index 92f7b1d3..feb7d0d6 100644 --- a/java_runtime/src/classes/java/util/linked_hash_map.rs +++ b/java_runtime/src/classes/java/util/linked_hash_map.rs @@ -120,7 +120,7 @@ impl LinkedHashMap { if map.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "map").await); } - let size: i32 = jvm.invoke_virtual(&map, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&map, &map.class_definition().name(), "size", "()I", ()).await?; let capacity = size.saturating_mul(2).max(DEFAULT_INITIAL_CAPACITY); let _: () = jvm .invoke_special( @@ -132,13 +132,21 @@ impl LinkedHashMap { ) .await?; - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - let entries: ClassInstanceRef> = jvm.invoke_virtual(&entry_set, "toArray", "()[Ljava/lang/Object;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let entries: ClassInstanceRef> = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let count = jvm.array_length(&entries).await?; let mut hash_map: ClassInstanceRef = ClassInstanceRef::new(this.instance); for entry in jvm.load_array::>(&entries, 0, count).await? { - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; HashMap::put_for_create(jvm, &mut hash_map, key, value).await?; } @@ -174,7 +182,8 @@ impl LinkedHashMap { } else if entry_value.is_null() { false } else { - jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (entry_value,)).await? + jvm.invoke_virtual(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (entry_value,)) + .await? }; if equal { return Ok(true); @@ -191,7 +200,9 @@ impl LinkedHashMap { if entry.is_null() { return Ok(None.into()); } - let _: () = jvm.invoke_virtual(&entry, "onAccess", "(Ljava/util/HashMap;)V", (map,)).await?; + let _: () = jvm + .invoke_virtual(&entry, "java/util/HashMap$Entry", "onAccess", "(Ljava/util/HashMap;)V", (map,)) + .await?; jvm.get_field(&entry, "value", "Ljava/lang/Object;").await } @@ -260,6 +271,7 @@ impl LinkedHashMap { let _: () = jvm .invoke_virtual( &this, + "java/util/HashMap", "storeNewEntry", "(ILjava/lang/Object;Ljava/lang/Object;I)V", (hash, key, value, bucket_index), @@ -270,12 +282,24 @@ impl LinkedHashMap { let eldest: ClassInstanceRef = jvm.get_field(&header, "after", "Ljava/util/LinkedHashMap$Entry;").await?; let eldest_entry: ClassInstanceRef = ClassInstanceRef::new(eldest.instance.clone()); if jvm - .invoke_virtual::<_, bool>(&this, "removeEldestEntry", "(Ljava/util/Map$Entry;)Z", (eldest_entry,)) + .invoke_virtual::<_, bool>( + &this, + "java/util/LinkedHashMap", + "removeEldestEntry", + "(Ljava/util/Map$Entry;)Z", + (eldest_entry,), + ) .await? { let key: ClassInstanceRef = jvm.get_field(&eldest, "key", "Ljava/lang/Object;").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&this, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual( + &this, + "java/util/LinkedHashMap", + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) .await?; } else { let threshold: i32 = jvm.get_field(&this, "threshold", "I").await?; diff --git a/java_runtime/src/classes/java/util/linked_hash_map_linked_hash_iterator.rs b/java_runtime/src/classes/java/util/linked_hash_map_linked_hash_iterator.rs index ef6ee387..8ea97c33 100644 --- a/java_runtime/src/classes/java/util/linked_hash_map_linked_hash_iterator.rs +++ b/java_runtime/src/classes/java/util/linked_hash_map_linked_hash_iterator.rs @@ -95,7 +95,13 @@ impl LinkedHashMapLinkedHashIterator { let key: ClassInstanceRef = jvm.get_field(&last_returned, "key", "Ljava/lang/Object;").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual( + &map, + "java/util/LinkedHashMap", + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) .await?; let last_returned: ClassInstanceRef = None.into(); jvm.put_field(&mut this, "lastReturned", "Ljava/util/LinkedHashMap$Entry;", last_returned) diff --git a/java_runtime/src/classes/java/util/linked_list.rs b/java_runtime/src/classes/java/util/linked_list.rs index 08a825f3..11dd9bb5 100644 --- a/java_runtime/src/classes/java/util/linked_list.rs +++ b/java_runtime/src/classes/java/util/linked_list.rs @@ -90,7 +90,9 @@ impl LinkedList { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } Self::init(jvm, context, this.clone()).await?; - let _: bool = jvm.invoke_virtual(&this, "addAll", "(Ljava/util/Collection;)Z", (collection,)).await?; + let _: bool = jvm + .invoke_virtual(&this, "java/util/LinkedList", "addAll", "(Ljava/util/Collection;)Z", (collection,)) + .await?; Ok(()) } @@ -197,7 +199,7 @@ impl LinkedList { let equal = if element.is_null() { current.is_null() } else { - jvm.invoke_virtual::<_, bool>(&element, "equals", "(Ljava/lang/Object;)Z", (current,)) + jvm.invoke_virtual::<_, bool>(&element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) .await? }; if equal { @@ -216,7 +218,7 @@ impl LinkedList { if (element.is_null() && current.is_null()) || (!element.is_null() && jvm - .invoke_virtual::<_, bool>(&element, "equals", "(Ljava/lang/Object;)Z", (current,)) + .invoke_virtual::<_, bool>(&element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) .await?) { return Ok(index); @@ -233,7 +235,7 @@ impl LinkedList { if (element.is_null() && current.is_null()) || (!element.is_null() && jvm - .invoke_virtual::<_, bool>(&element, "equals", "(Ljava/lang/Object;)Z", (current,)) + .invoke_virtual::<_, bool>(&element, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) .await?) { return Ok(index); @@ -244,7 +246,9 @@ impl LinkedList { async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { while jvm.get_field::(&this, "size", "I").await? > 0 { - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "removeFirst", "()Ljava/lang/Object;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/LinkedList", "removeFirst", "()Ljava/lang/Object;", ()) + .await?; } Ok(()) } diff --git a/java_runtime/src/classes/java/util/linked_list_itr.rs b/java_runtime/src/classes/java/util/linked_list_itr.rs index dbae76d8..27cdaecf 100644 --- a/java_runtime/src/classes/java/util/linked_list_itr.rs +++ b/java_runtime/src/classes/java/util/linked_list_itr.rs @@ -37,7 +37,7 @@ impl LinkedListItr { } async fn init(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, list: ClassInstanceRef, index: i32) -> Result<()> { - let size: i32 = jvm.invoke_virtual(&list, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&list, "java/util/LinkedList", "size", "()I", ()).await?; if index < 0 || index > size { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "list iterator index").await); } @@ -50,16 +50,18 @@ impl LinkedListItr { async fn has_next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/LinkedList;").await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; - Ok(cursor < jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?) + Ok(cursor < jvm.invoke_virtual::<_, i32>(&list, "java/util/LinkedList", "size", "()I", ()).await?) } async fn next(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result> { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/LinkedList;").await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; - if cursor >= jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await? { + if cursor >= jvm.invoke_virtual::<_, i32>(&list, "java/util/LinkedList", "size", "()I", ()).await? { return Err(jvm.exception("java/util/NoSuchElementException", "LinkedList iterator exhausted").await); } - let value = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (cursor,)).await?; + let value = jvm + .invoke_virtual(&list, "java/util/LinkedList", "get", "(I)Ljava/lang/Object;", (cursor,)) + .await?; jvm.put_field(&mut this, "cursor", "I", cursor + 1).await?; jvm.put_field(&mut this, "lastReturned", "I", cursor).await?; Ok(value) @@ -76,7 +78,9 @@ impl LinkedListItr { } let index = cursor - 1; let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/LinkedList;").await?; - let value = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (index,)).await?; + let value = jvm + .invoke_virtual(&list, "java/util/LinkedList", "get", "(I)Ljava/lang/Object;", (index,)) + .await?; jvm.put_field(&mut this, "cursor", "I", index).await?; jvm.put_field(&mut this, "lastReturned", "I", index).await?; Ok(value) @@ -96,7 +100,9 @@ impl LinkedListItr { return Err(jvm.exception("java/lang/IllegalStateException", "iterator state").await); } let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/LinkedList;").await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&list, "remove", "(I)Ljava/lang/Object;", (last_returned,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&list, "java/util/LinkedList", "remove", "(I)Ljava/lang/Object;", (last_returned,)) + .await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; if last_returned < cursor { jvm.put_field(&mut this, "cursor", "I", cursor - 1).await?; @@ -111,7 +117,13 @@ impl LinkedListItr { } let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/LinkedList;").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (last_returned, element)) + .invoke_virtual( + &list, + "java/util/LinkedList", + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (last_returned, element), + ) .await?; Ok(()) } @@ -119,7 +131,9 @@ impl LinkedListItr { async fn add(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, element: ClassInstanceRef) -> Result<()> { let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/LinkedList;").await?; - let _: () = jvm.invoke_virtual(&list, "add", "(ILjava/lang/Object;)V", (cursor, element)).await?; + let _: () = jvm + .invoke_virtual(&list, "java/util/LinkedList", "add", "(ILjava/lang/Object;)V", (cursor, element)) + .await?; jvm.put_field(&mut this, "cursor", "I", cursor + 1).await?; jvm.put_field(&mut this, "lastReturned", "I", -1).await } diff --git a/java_runtime/src/classes/java/util/logging/formatter.rs b/java_runtime/src/classes/java/util/logging/formatter.rs index 9342987c..42a9d810 100644 --- a/java_runtime/src/classes/java/util/logging/formatter.rs +++ b/java_runtime/src/classes/java/util/logging/formatter.rs @@ -69,12 +69,16 @@ impl Formatter { return Err(jvm.exception("java/lang/NullPointerException", "record").await); } - let message: ClassInstanceRef = jvm.invoke_virtual(&record, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getMessage", "()Ljava/lang/String;", ()) + .await?; if message.is_null() { return Ok(message); } - let parameters: ClassInstanceRef> = jvm.invoke_virtual(&record, "getParameters", "()[Ljava/lang/Object;", ()).await?; + let parameters: ClassInstanceRef> = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getParameters", "()[Ljava/lang/Object;", ()) + .await?; if parameters.is_null() { return Ok(message); } @@ -90,7 +94,9 @@ impl Formatter { replacements.push(if parameter.is_null() { RustString::from("null") } else { - let value: ClassInstanceRef = jvm.invoke_virtual(¶meter, "toString", "()Ljava/lang/String;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(¶meter, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; if value.is_null() { RustString::from("null") } else { diff --git a/java_runtime/src/classes/java/util/logging/handler.rs b/java_runtime/src/classes/java/util/logging/handler.rs index f469c293..643365fd 100644 --- a/java_runtime/src/classes/java/util/logging/handler.rs +++ b/java_runtime/src/classes/java/util/logging/handler.rs @@ -114,10 +114,16 @@ impl Handler { return Ok(false); } - let record_level: ClassInstanceRef = jvm.invoke_virtual(&record, "getLevel", "()Ljava/util/logging/Level;", ()).await?; + let record_level: ClassInstanceRef = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getLevel", "()Ljava/util/logging/Level;", ()) + .await?; let handler_level: ClassInstanceRef = jvm.get_field(&this, "level", "Ljava/util/logging/Level;").await?; - let record_value: i32 = jvm.invoke_virtual(&record_level, "intValue", "()I", ()).await?; - let handler_value: i32 = jvm.invoke_virtual(&handler_level, "intValue", "()I", ()).await?; + let record_value: i32 = jvm + .invoke_virtual(&record_level, "java/util/logging/Level", "intValue", "()I", ()) + .await?; + let handler_value: i32 = jvm + .invoke_virtual(&handler_level, "java/util/logging/Level", "intValue", "()I", ()) + .await?; if handler_value == i32::MAX || record_value < handler_value { return Ok(false); } @@ -127,8 +133,14 @@ impl Handler { return Ok(true); } - jvm.invoke_virtual(&filter, "isLoggable", "(Ljava/util/logging/LogRecord;)Z", (record,)) - .await + jvm.invoke_virtual( + &filter, + &filter.class_definition().name(), + "isLoggable", + "(Ljava/util/logging/LogRecord;)Z", + (record,), + ) + .await } async fn report_error( diff --git a/java_runtime/src/classes/java/util/logging/log_manager.rs b/java_runtime/src/classes/java/util/logging/log_manager.rs index 3f4aee96..c8f04313 100644 --- a/java_runtime/src/classes/java/util/logging/log_manager.rs +++ b/java_runtime/src/classes/java/util/logging/log_manager.rs @@ -105,11 +105,18 @@ impl LogManager { jvm.put_field(&mut root, "useParentHandlers", "Z", false).await?; let console: ClassInstanceRef = jvm.new_class("java/util/logging/ConsoleHandler", "()V", ()).await?.into(); let _: () = jvm - .invoke_virtual(&root, "addHandler", "(Ljava/util/logging/Handler;)V", (console,)) + .invoke_virtual( + &root, + "java/util/logging/Logger", + "addHandler", + "(Ljava/util/logging/Handler;)V", + (console,), + ) .await?; let _: ClassInstanceRef = jvm .invoke_virtual( &loggers, + "java/util/Hashtable", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (root_name, root.clone()), @@ -127,6 +134,7 @@ impl LogManager { let _: ClassInstanceRef = jvm .invoke_virtual( &loggers, + "java/util/Hashtable", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (global_name, global), @@ -146,7 +154,9 @@ impl LogManager { if logger.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "logger").await); } - let name: ClassInstanceRef = jvm.invoke_virtual(&logger, "getName", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm + .invoke_virtual(&logger, "java/util/logging/Logger", "getName", "()Ljava/lang/String;", ()) + .await?; if name.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "logger name").await); } @@ -170,7 +180,13 @@ impl LogManager { ) -> Result { let loggers: ClassInstanceRef = jvm.get_field(&this, "loggers", "Ljava/util/Hashtable;").await?; let existing: ClassInstanceRef = jvm - .invoke_virtual(&loggers, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (name.clone(),)) + .invoke_virtual( + &loggers, + "java/util/Hashtable", + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (name.clone(),), + ) .await?; if !existing.is_null() { return Ok(false); @@ -178,6 +194,7 @@ impl LogManager { let _: ClassInstanceRef = jvm .invoke_virtual( &loggers, + "java/util/Hashtable", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (name, logger), @@ -198,14 +215,15 @@ impl LogManager { return Err(jvm.exception("java/lang/NullPointerException", "name").await); } let loggers: ClassInstanceRef = jvm.get_field(&this, "loggers", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&loggers, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (name,)) + jvm.invoke_virtual(&loggers, "java/util/Hashtable", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (name,)) .await } async fn get_logger_names(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.util.logging.LogManager::getLoggerNames({this:?})"); let loggers: ClassInstanceRef = jvm.get_field(&this, "loggers", "Ljava/util/Hashtable;").await?; - jvm.invoke_virtual(&loggers, "keys", "()Ljava/util/Enumeration;", ()).await + jvm.invoke_virtual(&loggers, "java/util/Hashtable", "keys", "()Ljava/util/Enumeration;", ()) + .await } async fn reset(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { @@ -235,7 +253,7 @@ impl LogManager { let length = jvm.array_length(&handlers).await?; let handlers: Vec> = jvm.load_array(&handlers, 0, length).await?; for handler in handlers { - let _: () = jvm.invoke_virtual(&handler, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&handler, "java/util/logging/Handler", "close", "()V", ()).await?; } } Ok(()) @@ -243,10 +261,18 @@ impl LogManager { async fn snapshot_loggers(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result>> { let loggers: ClassInstanceRef = jvm.get_field(&this, "loggers", "Ljava/util/Hashtable;").await?; - let values: ClassInstanceRef = jvm.invoke_virtual(&loggers, "elements", "()Ljava/util/Enumeration;", ()).await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&loggers, "java/util/Hashtable", "elements", "()Ljava/util/Enumeration;", ()) + .await?; let mut snapshot: Vec> = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&values, "hasMoreElements", "()Z", ()).await? { - snapshot.push(jvm.invoke_virtual(&values, "nextElement", "()Ljava/lang/Object;", ()).await?); + while jvm + .invoke_virtual::<_, bool>(&values, &values.class_definition().name(), "hasMoreElements", "()Z", ()) + .await? + { + snapshot.push( + jvm.invoke_virtual(&values, &values.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?, + ); } let mut result: ClassInstanceRef> = jvm.instantiate_array("Ljava/util/logging/Logger;", snapshot.len()).await?.into(); @@ -262,10 +288,18 @@ impl LogManager { } async fn reconnect_parents(jvm: &Jvm, manager: &ClassInstanceRef, loggers: &ClassInstanceRef) -> Result<()> { - let names: ClassInstanceRef = jvm.invoke_virtual(loggers, "keys", "()Ljava/util/Enumeration;", ()).await?; + let names: ClassInstanceRef = jvm + .invoke_virtual(loggers, "java/util/Hashtable", "keys", "()Ljava/util/Enumeration;", ()) + .await?; let mut keys = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&names, "hasMoreElements", "()Z", ()).await? { - keys.push(jvm.invoke_virtual(&names, "nextElement", "()Ljava/lang/Object;", ()).await?); + while jvm + .invoke_virtual::<_, bool>(&names, &names.class_definition().name(), "hasMoreElements", "()Z", ()) + .await? + { + keys.push( + jvm.invoke_virtual(&names, &names.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?, + ); } let root: ClassInstanceRef = jvm.get_field(manager, "root", "Ljava/util/logging/Logger;").await?; @@ -275,7 +309,7 @@ impl LogManager { continue; } let mut logger: ClassInstanceRef = jvm - .invoke_virtual(loggers, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual(loggers, "java/util/Hashtable", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) .await?; let mut parent = root.clone(); let mut prefix = name.as_str(); @@ -283,7 +317,13 @@ impl LogManager { prefix = &prefix[..index]; let candidate_name = JavaLangString::from_rust_string(jvm, prefix).await?; let candidate: ClassInstanceRef = jvm - .invoke_virtual(loggers, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (candidate_name,)) + .invoke_virtual( + loggers, + "java/util/Hashtable", + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (candidate_name,), + ) .await?; if !candidate.is_null() { parent = candidate; diff --git a/java_runtime/src/classes/java/util/logging/logger.rs b/java_runtime/src/classes/java/util/logging/logger.rs index 5cecb6e8..16d853b3 100644 --- a/java_runtime/src/classes/java/util/logging/logger.rs +++ b/java_runtime/src/classes/java/util/logging/logger.rs @@ -335,7 +335,13 @@ impl Logger { .invoke_static("java/util/logging/LogManager", "getLogManager", "()Ljava/util/logging/LogManager;", ()) .await?; let mut logger: ClassInstanceRef = jvm - .invoke_virtual(&manager, "getLogger", "(Ljava/lang/String;)Ljava/util/logging/Logger;", (name.clone(),)) + .invoke_virtual( + &manager, + "java/util/logging/LogManager", + "getLogger", + "(Ljava/lang/String;)Ljava/util/logging/Logger;", + (name.clone(),), + ) .await?; if logger.is_null() { let candidate: ClassInstanceRef = jvm @@ -347,13 +353,25 @@ impl Logger { .await? .into(); let added: bool = jvm - .invoke_virtual(&manager, "addLogger", "(Ljava/util/logging/Logger;)Z", (candidate.clone(),)) + .invoke_virtual( + &manager, + "java/util/logging/LogManager", + "addLogger", + "(Ljava/util/logging/Logger;)Z", + (candidate.clone(),), + ) .await?; logger = if added { candidate } else { - jvm.invoke_virtual(&manager, "getLogger", "(Ljava/lang/String;)Ljava/util/logging/Logger;", (name,)) - .await? + jvm.invoke_virtual( + &manager, + "java/util/logging/LogManager", + "getLogger", + "(Ljava/lang/String;)Ljava/util/logging/Logger;", + (name,), + ) + .await? }; } @@ -427,7 +445,13 @@ impl Logger { .await?; let root_name = JavaLangString::from_rust_string(jvm, "").await?; let root: ClassInstanceRef = jvm - .invoke_virtual(&manager, "getLogger", "(Ljava/lang/String;)Ljava/util/logging/Logger;", (root_name,)) + .invoke_virtual( + &manager, + "java/util/logging/LogManager", + "getLogger", + "(Ljava/lang/String;)Ljava/util/logging/Logger;", + (root_name,), + ) .await?; jvm.put_field(&mut logger, "parent", "Ljava/util/logging/Logger;", root).await?; Ok(logger) @@ -493,7 +517,8 @@ impl Logger { return Err(jvm.exception("java/lang/NullPointerException", "handler").await); } let handlers: ClassInstanceRef = jvm.get_field(&this, "handlers", "Ljava/util/Vector;").await?; - jvm.invoke_virtual(&handlers, "addElement", "(Ljava/lang/Object;)V", (handler,)).await + jvm.invoke_virtual(&handlers, "java/util/Vector", "addElement", "(Ljava/lang/Object;)V", (handler,)) + .await } async fn remove_handler(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, handler: ClassInstanceRef) -> Result<()> { @@ -503,7 +528,7 @@ impl Logger { } let handlers: ClassInstanceRef = jvm.get_field(&this, "handlers", "Ljava/util/Vector;").await?; let _: bool = jvm - .invoke_virtual(&handlers, "removeElement", "(Ljava/lang/Object;)Z", (handler,)) + .invoke_virtual(&handlers, "java/util/Vector", "removeElement", "(Ljava/lang/Object;)Z", (handler,)) .await?; Ok(()) } @@ -511,10 +536,12 @@ impl Logger { async fn get_handlers(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result>> { tracing::debug!("java.util.logging.Logger::getHandlers({this:?})"); let handlers: ClassInstanceRef = jvm.get_field(&this, "handlers", "Ljava/util/Vector;").await?; - let size: i32 = jvm.invoke_virtual(&handlers, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&handlers, "java/util/Vector", "size", "()I", ()).await?; let mut result: ClassInstanceRef> = jvm.instantiate_array("Ljava/util/logging/Handler;", size as usize).await?.into(); for index in 0..size { - let handler: ClassInstanceRef = jvm.invoke_virtual(&handlers, "elementAt", "(I)Ljava/lang/Object;", (index,)).await?; + let handler: ClassInstanceRef = jvm + .invoke_virtual(&handlers, "java/util/Vector", "elementAt", "(I)Ljava/lang/Object;", (index,)) + .await?; jvm.store_array(&mut result, index as usize, [handler]).await?; } Ok(result) @@ -526,19 +553,19 @@ impl Logger { return Err(jvm.exception("java/lang/NullPointerException", "level").await); } - let requested: i32 = jvm.invoke_virtual(&level, "intValue", "()I", ()).await?; + let requested: i32 = jvm.invoke_virtual(&level, "java/util/logging/Level", "intValue", "()I", ()).await?; let mut logger = this; let effective = loop { let configured: ClassInstanceRef = jvm.get_field(&logger, "level", "Ljava/util/logging/Level;").await?; if !configured.is_null() { - break jvm.invoke_virtual(&configured, "intValue", "()I", ()).await?; + break jvm.invoke_virtual(&configured, "java/util/logging/Level", "intValue", "()I", ()).await?; } let parent: ClassInstanceRef = jvm.get_field(&logger, "parent", "Ljava/util/logging/Logger;").await?; if parent.is_null() { let info: ClassInstanceRef = jvm .get_static_field("java/util/logging/Level", "INFO", "Ljava/util/logging/Level;") .await?; - break jvm.invoke_virtual(&info, "intValue", "()I", ()).await?; + break jvm.invoke_virtual(&info, "java/util/logging/Level", "intValue", "()I", ()).await?; } logger = parent; }; @@ -551,9 +578,11 @@ impl Logger { if record.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "record").await); } - let level: ClassInstanceRef = jvm.invoke_virtual(&record, "getLevel", "()Ljava/util/logging/Level;", ()).await?; + let level: ClassInstanceRef = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getLevel", "()Ljava/util/logging/Level;", ()) + .await?; if !jvm - .invoke_virtual::<_, bool>(&this, "isLoggable", "(Ljava/util/logging/Level;)Z", (level,)) + .invoke_virtual::<_, bool>(&this, "java/util/logging/Logger", "isLoggable", "(Ljava/util/logging/Level;)Z", (level,)) .await? { return Ok(()); @@ -562,13 +591,21 @@ impl Logger { let filter: ClassInstanceRef = jvm.get_field(&this, "filter", "Ljava/util/logging/Filter;").await?; if !filter.is_null() && !jvm - .invoke_virtual::<_, bool>(&filter, "isLoggable", "(Ljava/util/logging/LogRecord;)Z", (record.clone(),)) + .invoke_virtual::<_, bool>( + &filter, + &filter.class_definition().name(), + "isLoggable", + "(Ljava/util/logging/LogRecord;)Z", + (record.clone(),), + ) .await? { return Ok(()); } - let logger_name: ClassInstanceRef = jvm.invoke_virtual(&record, "getLoggerName", "()Ljava/lang/String;", ()).await?; + let logger_name: ClassInstanceRef = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getLoggerName", "()Ljava/lang/String;", ()) + .await?; if logger_name.is_null() { let name: ClassInstanceRef = jvm.get_field(&this, "name", "Ljava/lang/String;").await?; jvm.put_field(&mut record, "loggerName", "Ljava/lang/String;", name).await?; @@ -576,12 +613,20 @@ impl Logger { let mut logger = this; loop { - let handlers: ClassInstanceRef> = jvm.invoke_virtual(&logger, "getHandlers", "()[Ljava/util/logging/Handler;", ()).await?; + let handlers: ClassInstanceRef> = jvm + .invoke_virtual(&logger, "java/util/logging/Logger", "getHandlers", "()[Ljava/util/logging/Handler;", ()) + .await?; let length = jvm.array_length(&handlers).await?; let handlers: Vec> = jvm.load_array(&handlers, 0, length).await?; for handler in handlers { let _: () = jvm - .invoke_virtual(&handler, "publish", "(Ljava/util/logging/LogRecord;)V", (record.clone(),)) + .invoke_virtual( + &handler, + "java/util/logging/Handler", + "publish", + "(Ljava/util/logging/LogRecord;)V", + (record.clone(),), + ) .await?; } @@ -1135,13 +1180,15 @@ impl Logger { async fn reset(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, root: bool) -> Result>> { let handlers: ClassInstanceRef = jvm.get_field(&this, "handlers", "Ljava/util/Vector;").await?; - let size: i32 = jvm.invoke_virtual(&handlers, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&handlers, "java/util/Vector", "size", "()I", ()).await?; let mut removed: ClassInstanceRef> = jvm.instantiate_array("Ljava/util/logging/Handler;", size as usize).await?.into(); for index in 0..size { - let handler: ClassInstanceRef = jvm.invoke_virtual(&handlers, "elementAt", "(I)Ljava/lang/Object;", (index,)).await?; + let handler: ClassInstanceRef = jvm + .invoke_virtual(&handlers, "java/util/Vector", "elementAt", "(I)Ljava/lang/Object;", (index,)) + .await?; jvm.store_array(&mut removed, index as usize, [handler]).await?; } - let _: () = jvm.invoke_virtual(&handlers, "removeAllElements", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&handlers, "java/util/Vector", "removeAllElements", "()V", ()).await?; let level: ClassInstanceRef = if root { jvm.get_static_field("java/util/logging/Level", "INFO", "Ljava/util/logging/Level;") @@ -1157,8 +1204,14 @@ impl Logger { let level: ClassInstanceRef = jvm .get_static_field("java/util/logging/Level", field, "Ljava/util/logging/Level;") .await?; - jvm.invoke_virtual(&this, "log", "(Ljava/util/logging/Level;Ljava/lang/String;)V", (level, message)) - .await + jvm.invoke_virtual( + &this, + "java/util/logging/Logger", + "log", + "(Ljava/util/logging/Level;Ljava/lang/String;)V", + (level, message), + ) + .await } #[allow(clippy::too_many_arguments)] @@ -1174,7 +1227,13 @@ impl Logger { resource_bundle_name: ClassInstanceRef, ) -> Result<()> { if !jvm - .invoke_virtual::<_, bool>(&this, "isLoggable", "(Ljava/util/logging/Level;)Z", (level.clone(),)) + .invoke_virtual::<_, bool>( + &this, + "java/util/logging/Logger", + "isLoggable", + "(Ljava/util/logging/Level;)Z", + (level.clone(),), + ) .await? { return Ok(()); @@ -1205,6 +1264,7 @@ impl Logger { jvm.put_field(&mut record, "resourceBundleName", "Ljava/lang/String;", resource_bundle_name) .await?; } - jvm.invoke_virtual(&this, "log", "(Ljava/util/logging/LogRecord;)V", (record,)).await + jvm.invoke_virtual(&this, "java/util/logging/Logger", "log", "(Ljava/util/logging/LogRecord;)V", (record,)) + .await } } diff --git a/java_runtime/src/classes/java/util/logging/simple_formatter.rs b/java_runtime/src/classes/java/util/logging/simple_formatter.rs index 19fdf3a0..6ebc60e8 100644 --- a/java_runtime/src/classes/java/util/logging/simple_formatter.rs +++ b/java_runtime/src/classes/java/util/logging/simple_formatter.rs @@ -55,9 +55,15 @@ impl SimpleFormatter { return Err(jvm.exception("java/lang/NullPointerException", "record").await); } - let source_class: ClassInstanceRef = jvm.invoke_virtual(&record, "getSourceClassName", "()Ljava/lang/String;", ()).await?; - let source_method: ClassInstanceRef = jvm.invoke_virtual(&record, "getSourceMethodName", "()Ljava/lang/String;", ()).await?; - let logger_name: ClassInstanceRef = jvm.invoke_virtual(&record, "getLoggerName", "()Ljava/lang/String;", ()).await?; + let source_class: ClassInstanceRef = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getSourceClassName", "()Ljava/lang/String;", ()) + .await?; + let source_method: ClassInstanceRef = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getSourceMethodName", "()Ljava/lang/String;", ()) + .await?; + let logger_name: ClassInstanceRef = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getLoggerName", "()Ljava/lang/String;", ()) + .await?; let mut source = if source_class.is_null() { if logger_name.is_null() { RustString::new() @@ -74,12 +80,17 @@ impl SimpleFormatter { source.push_str(&JavaLangString::to_rust_string(jvm, &source_method).await?); } - let level: ClassInstanceRef = jvm.invoke_virtual(&record, "getLevel", "()Ljava/util/logging/Level;", ()).await?; - let level_name: ClassInstanceRef = jvm.invoke_virtual(&level, "getName", "()Ljava/lang/String;", ()).await?; + let level: ClassInstanceRef = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getLevel", "()Ljava/util/logging/Level;", ()) + .await?; + let level_name: ClassInstanceRef = jvm + .invoke_virtual(&level, "java/util/logging/Level", "getName", "()Ljava/lang/String;", ()) + .await?; let level_name = JavaLangString::to_rust_string(jvm, &level_name).await?; let message: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/util/logging/SimpleFormatter", "formatMessage", "(Ljava/util/logging/LogRecord;)Ljava/lang/String;", (record.clone(),), @@ -96,7 +107,9 @@ impl SimpleFormatter { } else { format!("{source} {level_name}: {message}\n") }; - let thrown: ClassInstanceRef = jvm.invoke_virtual(&record, "getThrown", "()Ljava/lang/Throwable;", ()).await?; + let thrown: ClassInstanceRef = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "getThrown", "()Ljava/lang/Throwable;", ()) + .await?; if !thrown.is_null() { let string_writer: ClassInstanceRef = jvm.new_class("java/io/StringWriter", "()V", ()).await?.into(); let print_writer: ClassInstanceRef = jvm @@ -104,9 +117,17 @@ impl SimpleFormatter { .await? .into(); let _: () = jvm - .invoke_virtual(&thrown, "printStackTrace", "(Ljava/io/PrintWriter;)V", (print_writer,)) + .invoke_virtual( + &thrown, + "java/lang/Throwable", + "printStackTrace", + "(Ljava/io/PrintWriter;)V", + (print_writer,), + ) + .await?; + let trace: ClassInstanceRef = jvm + .invoke_virtual(&string_writer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) .await?; - let trace: ClassInstanceRef = jvm.invoke_virtual(&string_writer, "toString", "()Ljava/lang/String;", ()).await?; formatted.push_str(&JavaLangString::to_rust_string(jvm, &trace).await?); } diff --git a/java_runtime/src/classes/java/util/logging/stream_handler.rs b/java_runtime/src/classes/java/util/logging/stream_handler.rs index 91f4c314..e59c4af6 100644 --- a/java_runtime/src/classes/java/util/logging/stream_handler.rs +++ b/java_runtime/src/classes/java/util/logging/stream_handler.rs @@ -135,8 +135,8 @@ impl StreamHandler { } Self::write_tail(jvm, &this).await?; - let _: () = jvm.invoke_virtual(&writer, "flush", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/OutputStreamWriter", "flush", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/OutputStreamWriter", "close", "()V", ()).await?; let output: ClassInstanceRef = None.into(); let writer: ClassInstanceRef = None.into(); jvm.put_field(&mut this, "output", "Ljava/io/OutputStream;", output).await?; @@ -151,7 +151,7 @@ impl StreamHandler { if writer.is_null() { return Ok(()); } - jvm.invoke_virtual(&writer, "flush", "()V", ()).await + jvm.invoke_virtual(&writer, "java/io/OutputStreamWriter", "flush", "()V", ()).await } async fn is_loggable(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, record: ClassInstanceRef) -> Result { @@ -176,7 +176,13 @@ impl StreamHandler { tracing::debug!("java.util.logging.StreamHandler::publish({this:?}, {record:?})"); let loggable: bool = jvm - .invoke_virtual(&this, "isLoggable", "(Ljava/util/logging/LogRecord;)Z", (record.clone(),)) + .invoke_virtual( + &this, + "java/util/logging/StreamHandler", + "isLoggable", + "(Ljava/util/logging/LogRecord;)Z", + (record.clone(),), + ) .await?; if !loggable { return Ok(()); @@ -191,6 +197,7 @@ impl StreamHandler { let _: () = jvm .invoke_virtual( &this, + "java/util/logging/StreamHandler", "reportError", "(Ljava/lang/String;Ljava/lang/Exception;I)V", (message, exception, 1), @@ -200,7 +207,13 @@ impl StreamHandler { } let formatter: ClassInstanceRef = jvm.get_field(&this, "formatter", "Ljava/util/logging/Formatter;").await?; let formatted: ClassInstanceRef = match jvm - .invoke_virtual(&formatter, "format", "(Ljava/util/logging/LogRecord;)Ljava/lang/String;", (record,)) + .invoke_virtual( + &formatter, + "java/util/logging/Formatter", + "format", + "(Ljava/util/logging/LogRecord;)Ljava/lang/String;", + (record,), + ) .await { Ok(formatted) => formatted, @@ -213,6 +226,7 @@ impl StreamHandler { let _: () = jvm .invoke_virtual( &this, + "java/util/logging/StreamHandler", "reportError", "(Ljava/lang/String;Ljava/lang/Exception;I)V", (message, exception, 5), @@ -222,7 +236,10 @@ impl StreamHandler { } }; let writer: ClassInstanceRef = jvm.get_field(&this, "writer", "Ljava/io/OutputStreamWriter;").await?; - if let Err(JavaError::JavaException(exception)) = jvm.invoke_virtual::<_, ()>(&writer, "write", "(Ljava/lang/String;)V", (formatted,)).await { + if let Err(JavaError::JavaException(exception)) = jvm + .invoke_virtual::<_, ()>(&writer, "java/io/OutputStreamWriter", "write", "(Ljava/lang/String;)V", (formatted,)) + .await + { if !jvm.is_instance(&*exception, "java/lang/Exception") { return Err(JavaError::JavaException(exception)); } @@ -231,6 +248,7 @@ impl StreamHandler { let _: () = jvm .invoke_virtual( &this, + "java/util/logging/StreamHandler", "reportError", "(Ljava/lang/String;Ljava/lang/Exception;I)V", (message, exception, 1), @@ -259,7 +277,7 @@ impl StreamHandler { } let writer: ClassInstanceRef = jvm.get_field(&this, "writer", "Ljava/io/OutputStreamWriter;").await?; - let _: () = jvm.invoke_virtual(&writer, "flush", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/OutputStreamWriter", "flush", "()V", ()).await?; let writer: ClassInstanceRef = if encoding.is_null() { jvm.new_class("java/io/OutputStreamWriter", "(Ljava/io/OutputStream;)V", (output,)) .await? @@ -291,8 +309,12 @@ impl StreamHandler { let current_writer: ClassInstanceRef = jvm.get_field(&this, "writer", "Ljava/io/OutputStreamWriter;").await?; if !current_writer.is_null() { Self::write_tail(jvm, &this).await?; - let _: () = jvm.invoke_virtual(¤t_writer, "flush", "()V", ()).await?; - let _: () = jvm.invoke_virtual(¤t_writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(¤t_writer, "java/io/OutputStreamWriter", "flush", "()V", ()) + .await?; + let _: () = jvm + .invoke_virtual(¤t_writer, "java/io/OutputStreamWriter", "close", "()V", ()) + .await?; } let encoding: ClassInstanceRef = jvm.get_field(&this, "encoding", "Ljava/lang/String;").await?; @@ -321,10 +343,18 @@ impl StreamHandler { let formatter: ClassInstanceRef = jvm.get_field(this, "formatter", "Ljava/util/logging/Formatter;").await?; let head: ClassInstanceRef = jvm - .invoke_virtual(&formatter, "getHead", "(Ljava/util/logging/Handler;)Ljava/lang/String;", (this.clone(),)) + .invoke_virtual( + &formatter, + "java/util/logging/Formatter", + "getHead", + "(Ljava/util/logging/Handler;)Ljava/lang/String;", + (this.clone(),), + ) .await?; let writer: ClassInstanceRef = jvm.get_field(this, "writer", "Ljava/io/OutputStreamWriter;").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (head,)).await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/OutputStreamWriter", "write", "(Ljava/lang/String;)V", (head,)) + .await?; let mut this = this.clone(); jvm.put_field(&mut this, "headerWritten", "Z", true).await } @@ -333,9 +363,16 @@ impl StreamHandler { Self::write_head(jvm, this).await?; let formatter: ClassInstanceRef = jvm.get_field(this, "formatter", "Ljava/util/logging/Formatter;").await?; let tail: ClassInstanceRef = jvm - .invoke_virtual(&formatter, "getTail", "(Ljava/util/logging/Handler;)Ljava/lang/String;", (this.clone(),)) + .invoke_virtual( + &formatter, + "java/util/logging/Formatter", + "getTail", + "(Ljava/util/logging/Handler;)Ljava/lang/String;", + (this.clone(),), + ) .await?; let writer: ClassInstanceRef = jvm.get_field(this, "writer", "Ljava/io/OutputStreamWriter;").await?; - jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (tail,)).await + jvm.invoke_virtual(&writer, "java/io/OutputStreamWriter", "write", "(Ljava/lang/String;)V", (tail,)) + .await } } diff --git a/java_runtime/src/classes/java/util/properties.rs b/java_runtime/src/classes/java/util/properties.rs index 6f9f34bb..68f4da37 100644 --- a/java_runtime/src/classes/java/util/properties.rs +++ b/java_runtime/src/classes/java/util/properties.rs @@ -92,7 +92,13 @@ impl Properties { tracing::debug!("java.util.Properties::getProperty({this:?}, {key:?})"); let result: ClassInstanceRef = jvm - .invoke_virtual(&this, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) + .invoke_virtual( + &this, + "java/util/Properties", + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),), + ) .await?; if !result.is_null() && jvm.is_instance(&**result, "java/lang/String") { return Ok(ClassInstanceRef::new(result.instance)); @@ -102,8 +108,14 @@ impl Properties { if defaults.is_null() { Ok(None.into()) } else { - jvm.invoke_virtual(&defaults, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) - .await + jvm.invoke_virtual( + &defaults, + "java/util/Properties", + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) + .await } } @@ -117,7 +129,13 @@ impl Properties { tracing::debug!("java.util.Properties::getProperty({this:?}, {key:?}, {default_value:?})"); let value: ClassInstanceRef = jvm - .invoke_virtual(&this, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &this, + "java/util/Properties", + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; if value.is_null() { Ok(default_value) } else { Ok(value) } } @@ -131,8 +149,14 @@ impl Properties { ) -> Result> { tracing::debug!("java.util.Properties::setProperty({this:?}, {key:?}, {value:?})"); - jvm.invoke_virtual(&this, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) - .await + jvm.invoke_virtual( + &this, + "java/util/Properties", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) + .await } async fn load(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, input: ClassInstanceRef) -> Result<()> { @@ -146,7 +170,7 @@ impl Properties { let mut skip_lf = false; let mut skip_leading_whitespace = false; loop { - let value: i32 = jvm.invoke_virtual(&input, "read", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&input, "java/io/InputStream", "read", "()I", ()).await?; if value < 0 { if !logical_line.is_empty() { let trailing_backslashes = logical_line.iter().rev().take_while(|character| **character == b'\\' as JavaChar).count(); @@ -253,7 +277,13 @@ impl Properties { let key = JavaLangString::from_utf16(jvm, key_chars).await?; let value = JavaLangString::from_utf16(jvm, value_chars).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(this, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + this, + "java/util/Properties", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; Ok(()) } @@ -296,16 +326,31 @@ impl Properties { text.push('\n'); } let date = jvm.new_class("java/util/Date", "()V", ()).await?; - let date: ClassInstanceRef = jvm.invoke_virtual(&date, "toString", "()Ljava/lang/String;", ()).await?; + let date: ClassInstanceRef = jvm + .invoke_virtual(&date, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; text.push('#'); text.push_str(&JavaLangString::to_rust_string(jvm, &date).await?); text.push('\n'); - let names: ClassInstanceRef = jvm.invoke_virtual(&this, "keys", "()Ljava/util/Enumeration;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&names, "hasMoreElements", "()Z", ()).await? { - let key: ClassInstanceRef = jvm.invoke_virtual(&names, "nextElement", "()Ljava/lang/Object;", ()).await?; + let names: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/Properties", "keys", "()Ljava/util/Enumeration;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&names, &names.class_definition().name(), "hasMoreElements", "()Z", ()) + .await? + { + let key: ClassInstanceRef = jvm + .invoke_virtual(&names, &names.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; let value: ClassInstanceRef = jvm - .invoke_virtual(&this, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) + .invoke_virtual( + &this, + "java/util/Properties", + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),), + ) .await?; if !jvm.is_instance(&**key, "java/lang/String") || value.is_null() || !jvm.is_instance(&**value, "java/lang/String") { return Err(jvm @@ -324,15 +369,18 @@ impl Properties { let bytes = text.into_bytes(); let mut byte_array = jvm.instantiate_array("B", bytes.len()).await?; jvm.store_array(&mut byte_array, 0, bytes.into_iter().map(|byte| byte as i8)).await?; - let _: () = jvm.invoke_virtual(&output, "write", "([B)V", (byte_array,)).await?; - jvm.invoke_virtual(&output, "flush", "()V", ()).await + let _: () = jvm + .invoke_virtual(&output, "java/io/OutputStream", "write", "([B)V", (byte_array,)) + .await?; + jvm.invoke_virtual(&output, "java/io/OutputStream", "flush", "()V", ()).await } async fn property_names(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.util.Properties::propertyNames({this:?})"); let table = Self::enumerate(jvm, &this).await?; - jvm.invoke_virtual(&table, "keys", "()Ljava/util/Enumeration;", ()).await + jvm.invoke_virtual(&table, "java/util/Hashtable", "keys", "()Ljava/util/Enumeration;", ()) + .await } async fn enumerate(jvm: &Jvm, this: &ClassInstanceRef) -> Result> { @@ -345,17 +393,36 @@ impl Properties { } for layer in layers.into_iter().rev() { - let names: ClassInstanceRef = jvm.invoke_virtual(&layer, "keys", "()Ljava/util/Enumeration;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&names, "hasMoreElements", "()Z", ()).await? { - let key: ClassInstanceRef = jvm.invoke_virtual(&names, "nextElement", "()Ljava/lang/Object;", ()).await?; + let names: ClassInstanceRef = jvm + .invoke_virtual(&layer, "java/util/Properties", "keys", "()Ljava/util/Enumeration;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&names, &names.class_definition().name(), "hasMoreElements", "()Z", ()) + .await? + { + let key: ClassInstanceRef = jvm + .invoke_virtual(&names, &names.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; if key.is_null() || !jvm.is_instance(&**key, "java/lang/String") { return Err(jvm.exception("java/lang/ClassCastException", "Properties key must be String").await); } let value: ClassInstanceRef = jvm - .invoke_virtual(&layer, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) + .invoke_virtual( + &layer, + "java/util/Properties", + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&table, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &table, + "java/util/Hashtable", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } } diff --git a/java_runtime/src/classes/java/util/random.rs b/java_runtime/src/classes/java/util/random.rs index 698d77f8..76431426 100644 --- a/java_runtime/src/classes/java/util/random.rs +++ b/java_runtime/src/classes/java/util/random.rs @@ -62,7 +62,7 @@ impl Random { let _: () = jvm.invoke_special(&this, "java/lang/Object", "", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&this, "setSeed", "(J)V", (seed,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/util/Random", "setSeed", "(J)V", (seed,)).await?; Ok(()) } @@ -83,7 +83,7 @@ impl Random { async fn next_boolean(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.util.Random::nextBoolean({this:?})"); - let value: i32 = jvm.invoke_virtual(&this, "next", "(I)I", (1,)).await?; + let value: i32 = jvm.invoke_virtual(&this, "java/util/Random", "next", "(I)I", (1,)).await?; Ok(value != 0) } @@ -97,7 +97,7 @@ impl Random { let length = jvm.array_length(&bytes).await?; let mut index = 0; while index < length { - let mut random: i32 = jvm.invoke_virtual(&this, "nextInt", "()I", ()).await?; + let mut random: i32 = jvm.invoke_virtual(&this, "java/util/Random", "nextInt", "()I", ()).await?; let chunk_length = core::cmp::min(length - index, 4); let mut chunk = alloc::vec::Vec::with_capacity(chunk_length); for _ in 0..chunk_length { @@ -113,7 +113,7 @@ impl Random { async fn next_int(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.util.Random::nextInt({this:?})"); - jvm.invoke_virtual(&this, "next", "(I)I", (32,)).await + jvm.invoke_virtual(&this, "java/util/Random", "next", "(I)I", (32,)).await } async fn next_int_with_bound(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, bound: i32) -> Result { @@ -124,12 +124,12 @@ impl Random { } if (bound as u32).is_power_of_two() { - let bits: i32 = jvm.invoke_virtual(&this, "next", "(I)I", (31,)).await?; + let bits: i32 = jvm.invoke_virtual(&this, "java/util/Random", "next", "(I)I", (31,)).await?; return Ok(((bound as i64 * bits as i64) >> 31) as i32); } loop { - let bits: i32 = jvm.invoke_virtual(&this, "next", "(I)I", (31,)).await?; + let bits: i32 = jvm.invoke_virtual(&this, "java/util/Random", "next", "(I)I", (31,)).await?; let value = bits % bound; if bits.wrapping_sub(value).wrapping_add(bound - 1) >= 0 { return Ok(value); @@ -140,23 +140,23 @@ impl Random { async fn next_long(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.util.Random::nextLong({this:?})"); - let high: i32 = jvm.invoke_virtual(&this, "next", "(I)I", (32,)).await?; - let low: i32 = jvm.invoke_virtual(&this, "next", "(I)I", (32,)).await?; + let high: i32 = jvm.invoke_virtual(&this, "java/util/Random", "next", "(I)I", (32,)).await?; + let low: i32 = jvm.invoke_virtual(&this, "java/util/Random", "next", "(I)I", (32,)).await?; Ok((high as i64).wrapping_shl(32).wrapping_add(low as i64)) } async fn next_float(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.util.Random::nextFloat({this:?})"); - let bits: i32 = jvm.invoke_virtual(&this, "next", "(I)I", (24,)).await?; + let bits: i32 = jvm.invoke_virtual(&this, "java/util/Random", "next", "(I)I", (24,)).await?; Ok(bits as f32 / (1u32 << 24) as f32) } async fn next_double(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::debug!("java.util.Random::nextDouble({this:?})"); - let high: i32 = jvm.invoke_virtual(&this, "next", "(I)I", (26,)).await?; - let low: i32 = jvm.invoke_virtual(&this, "next", "(I)I", (27,)).await?; + let high: i32 = jvm.invoke_virtual(&this, "java/util/Random", "next", "(I)I", (26,)).await?; + let low: i32 = jvm.invoke_virtual(&this, "java/util/Random", "next", "(I)I", (27,)).await?; Ok(((high as i64) << 27 | low as i64) as f64 / (1u64 << 53) as f64) } @@ -171,8 +171,8 @@ impl Random { } let (first, second, radius_squared) = loop { - let first = 2.0 * jvm.invoke_virtual::<_, f64>(&this, "nextDouble", "()D", ()).await? - 1.0; - let second = 2.0 * jvm.invoke_virtual::<_, f64>(&this, "nextDouble", "()D", ()).await? - 1.0; + let first = 2.0 * jvm.invoke_virtual::<_, f64>(&this, "java/util/Random", "nextDouble", "()D", ()).await? - 1.0; + let second = 2.0 * jvm.invoke_virtual::<_, f64>(&this, "java/util/Random", "nextDouble", "()D", ()).await? - 1.0; let radius_squared = first * first + second * second; if radius_squared < 1.0 && radius_squared != 0.0 { break (first, second, radius_squared); diff --git a/java_runtime/src/classes/java/util/regex/matcher.rs b/java_runtime/src/classes/java/util/regex/matcher.rs index 5e79e036..afaed226 100644 --- a/java_runtime/src/classes/java/util/regex/matcher.rs +++ b/java_runtime/src/classes/java/util/regex/matcher.rs @@ -215,7 +215,7 @@ impl Matcher { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "Illegal start index").await); } let text: ClassInstanceRef = jvm.get_field(&this, "text", "Ljava/lang/CharSequence;").await?; - let length: i32 = jvm.invoke_virtual(&text, "length", "()I", ()).await?; + let length: i32 = jvm.invoke_virtual(&text, &text.class_definition().name(), "length", "()I", ()).await?; if start > length { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "Illegal start index").await); } @@ -257,9 +257,16 @@ impl Matcher { let (start, end) = Self::group_range(jvm, &this, 0).await?; let text: ClassInstanceRef = jvm.get_field(&this, "text", "Ljava/lang/CharSequence;").await?; let group: ClassInstanceRef = jvm - .invoke_virtual(&text, "subSequence", "(II)Ljava/lang/CharSequence;", (start, end)) + .invoke_virtual( + &text, + &text.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (start, end), + ) .await?; - jvm.invoke_virtual(&group, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&group, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn group_index(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, group: i32) -> Result> { @@ -271,9 +278,16 @@ impl Matcher { } let text: ClassInstanceRef = jvm.get_field(&this, "text", "Ljava/lang/CharSequence;").await?; let group: ClassInstanceRef = jvm - .invoke_virtual(&text, "subSequence", "(II)Ljava/lang/CharSequence;", (start, end)) + .invoke_virtual( + &text, + &text.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (start, end), + ) .await?; - jvm.invoke_virtual(&group, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&group, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn group_count(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -303,19 +317,39 @@ impl Matcher { let append_position: i32 = jvm.get_field(&this, "appendPosition", "I").await?; let text: ClassInstanceRef = jvm.get_field(&this, "text", "Ljava/lang/CharSequence;").await?; let prefix: ClassInstanceRef = jvm - .invoke_virtual(&text, "subSequence", "(II)Ljava/lang/CharSequence;", (append_position, match_range[0])) + .invoke_virtual( + &text, + &text.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (append_position, match_range[0]), + ) + .await?; + let prefix: ClassInstanceRef = jvm + .invoke_virtual(&prefix, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) .await?; - let prefix: ClassInstanceRef = jvm.invoke_virtual(&prefix, "toString", "()Ljava/lang/String;", ()).await?; let expanded = JavaLangString::from_utf16(jvm, expanded).await?; if buffer.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "buffer is null").await); } let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (prefix,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (prefix,), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (expanded,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (expanded,), + ) .await?; jvm.put_field(&mut this, "appendPosition", "I", match_range[1]).await?; Ok(this) @@ -335,13 +369,27 @@ impl Matcher { let append_position: i32 = jvm.get_field(&this, "appendPosition", "I").await?; let text: ClassInstanceRef = jvm.get_field(&this, "text", "Ljava/lang/CharSequence;").await?; - let length: i32 = jvm.invoke_virtual(&text, "length", "()I", ()).await?; + let length: i32 = jvm.invoke_virtual(&text, &text.class_definition().name(), "length", "()I", ()).await?; let tail: ClassInstanceRef = jvm - .invoke_virtual(&text, "subSequence", "(II)Ljava/lang/CharSequence;", (append_position, length)) + .invoke_virtual( + &text, + &text.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (append_position, length), + ) .await?; - let tail: ClassInstanceRef = jvm.invoke_virtual(&tail, "toString", "()Ljava/lang/String;", ()).await?; - jvm.invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (tail,)) - .await + let tail: ClassInstanceRef = jvm + .invoke_virtual(&tail, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; + jvm.invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (tail,), + ) + .await } async fn replace_all( @@ -352,10 +400,14 @@ impl Matcher { ) -> Result> { tracing::debug!("java.util.regex.Matcher::replaceAll({this:?}, {replacement:?})"); - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "reset", "()Ljava/util/regex/Matcher;", ()).await?; - if !jvm.invoke_virtual::<_, bool>(&this, "find", "()Z", ()).await? { + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/regex/Matcher", "reset", "()Ljava/util/regex/Matcher;", ()) + .await?; + if !jvm.invoke_virtual::<_, bool>(&this, "java/util/regex/Matcher", "find", "()Z", ()).await? { let text: ClassInstanceRef = jvm.get_field(&this, "text", "Ljava/lang/CharSequence;").await?; - return jvm.invoke_virtual(&text, "toString", "()Ljava/lang/String;", ()).await; + return jvm + .invoke_virtual(&text, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await; } let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?.into(); @@ -363,24 +415,27 @@ impl Matcher { let _: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (buffer.clone(), replacement.clone()), ) .await?; - if !jvm.invoke_virtual::<_, bool>(&this, "find", "()Z", ()).await? { + if !jvm.invoke_virtual::<_, bool>(&this, "java/util/regex/Matcher", "find", "()Z", ()).await? { break; } } let _: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/util/regex/Matcher", "appendTail", "(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;", (buffer.clone(),), ) .await?; - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn replace_first( @@ -391,16 +446,21 @@ impl Matcher { ) -> Result> { tracing::debug!("java.util.regex.Matcher::replaceFirst({this:?}, {replacement:?})"); - let _: ClassInstanceRef = jvm.invoke_virtual(&this, "reset", "()Ljava/util/regex/Matcher;", ()).await?; - if !jvm.invoke_virtual::<_, bool>(&this, "find", "()Z", ()).await? { + let _: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/regex/Matcher", "reset", "()Ljava/util/regex/Matcher;", ()) + .await?; + if !jvm.invoke_virtual::<_, bool>(&this, "java/util/regex/Matcher", "find", "()Z", ()).await? { let text: ClassInstanceRef = jvm.get_field(&this, "text", "Ljava/lang/CharSequence;").await?; - return jvm.invoke_virtual(&text, "toString", "()Ljava/lang/String;", ()).await; + return jvm + .invoke_virtual(&text, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await; } let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?.into(); let _: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (buffer.clone(), replacement), @@ -409,12 +469,14 @@ impl Matcher { let _: ClassInstanceRef = jvm .invoke_virtual( &this, + "java/util/regex/Matcher", "appendTail", "(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;", (buffer.clone(),), ) .await?; - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } async fn group_range(jvm: &Jvm, this: &ClassInstanceRef, group: i32) -> Result<(i32, i32)> { @@ -485,9 +547,17 @@ impl Matcher { let start = ranges[group * 2]; if start >= 0 { let group: ClassInstanceRef = jvm - .invoke_virtual(&text, "subSequence", "(II)Ljava/lang/CharSequence;", (start, ranges[group * 2 + 1])) + .invoke_virtual( + &text, + &text.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (start, ranges[group * 2 + 1]), + ) + .await?; + let group: ClassInstanceRef = jvm + .invoke_virtual(&group, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) .await?; - let group: ClassInstanceRef = jvm.invoke_virtual(&group, "toString", "()Ljava/lang/String;", ()).await?; expanded.extend(JavaLangString::to_utf16(jvm, &group).await?); } } @@ -512,7 +582,9 @@ impl Matcher { } let text: ClassInstanceRef = jvm.get_field(this, "text", "Ljava/lang/CharSequence;").await?; - let snapshot: ClassInstanceRef = jvm.invoke_virtual(&text, "toString", "()Ljava/lang/String;", ()).await?; + let snapshot: ClassInstanceRef = jvm + .invoke_virtual(&text, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; let utf16 = JavaLangString::to_utf16(jvm, &snapshot).await?; let rust = RustString::from_utf16_lossy(&utf16); diff --git a/java_runtime/src/classes/java/util/regex/pattern.rs b/java_runtime/src/classes/java/util/regex/pattern.rs index 59d4f2e4..c81aae71 100644 --- a/java_runtime/src/classes/java/util/regex/pattern.rs +++ b/java_runtime/src/classes/java/util/regex/pattern.rs @@ -199,9 +199,15 @@ impl Pattern { ) .await?; let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - jvm.invoke_virtual(&matcher, "matches", "()Z", ()).await + jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "matches", "()Z", ()).await } async fn split( @@ -212,8 +218,14 @@ impl Pattern { ) -> Result>> { tracing::debug!("java.util.regex.Pattern::split({this:?}, {input:?})"); - jvm.invoke_virtual(&this, "split", "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", (input, 0)) - .await + jvm.invoke_virtual( + &this, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", + (input, 0), + ) + .await } async fn split_with_limit( @@ -226,43 +238,86 @@ impl Pattern { tracing::debug!("java.util.regex.Pattern::split({this:?}, {input:?}, {limit})"); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&this, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input.clone(),)) + .invoke_virtual( + &this, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input.clone(),), + ) .await?; - let input_length: i32 = jvm.invoke_virtual(&input, "length", "()I", ()).await?; + let input_length: i32 = jvm.invoke_virtual(&input, &input.class_definition().name(), "length", "()I", ()).await?; let match_limited = limit > 0; let mut index = 0; let mut parts = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await? { + while jvm + .invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + { if !match_limited || parts.len() < (limit - 1) as usize { - let start: i32 = jvm.invoke_virtual(&matcher, "start", "()I", ()).await?; + let start: i32 = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "start", "()I", ()).await?; let part: ClassInstanceRef = jvm - .invoke_virtual(&input, "subSequence", "(II)Ljava/lang/CharSequence;", (index, start)) + .invoke_virtual( + &input, + &input.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (index, start), + ) .await?; - parts.push(jvm.invoke_virtual(&part, "toString", "()Ljava/lang/String;", ()).await?); - index = jvm.invoke_virtual(&matcher, "end", "()I", ()).await?; + parts.push( + jvm.invoke_virtual(&part, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?, + ); + index = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "end", "()I", ()).await?; } else if parts.len() == (limit - 1) as usize { let part: ClassInstanceRef = jvm - .invoke_virtual(&input, "subSequence", "(II)Ljava/lang/CharSequence;", (index, input_length)) + .invoke_virtual( + &input, + &input.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (index, input_length), + ) .await?; - parts.push(jvm.invoke_virtual(&part, "toString", "()Ljava/lang/String;", ()).await?); - index = jvm.invoke_virtual(&matcher, "end", "()I", ()).await?; + parts.push( + jvm.invoke_virtual(&part, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?, + ); + index = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "end", "()I", ()).await?; } } if index == 0 { parts.clear(); - parts.push(jvm.invoke_virtual(&input, "toString", "()Ljava/lang/String;", ()).await?); + parts.push( + jvm.invoke_virtual(&input, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?, + ); } else { if !match_limited || parts.len() < limit as usize { let part: ClassInstanceRef = jvm - .invoke_virtual(&input, "subSequence", "(II)Ljava/lang/CharSequence;", (index, input_length)) + .invoke_virtual( + &input, + &input.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (index, input_length), + ) .await?; - parts.push(jvm.invoke_virtual(&part, "toString", "()Ljava/lang/String;", ()).await?); + parts.push( + jvm.invoke_virtual(&part, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?, + ); } if limit == 0 { while let Some(part) = parts.last() { - if jvm.invoke_virtual::<_, i32>(part, "length", "()I", ()).await? != 0 { + if jvm + .invoke_virtual::<_, i32>(part, &part.class_definition().name(), "length", "()I", ()) + .await? + != 0 + { break; } parts.pop(); diff --git a/java_runtime/src/classes/java/util/regex/pattern_syntax_exception.rs b/java_runtime/src/classes/java/util/regex/pattern_syntax_exception.rs index 7da80718..d337eeb9 100644 --- a/java_runtime/src/classes/java/util/regex/pattern_syntax_exception.rs +++ b/java_runtime/src/classes/java/util/regex/pattern_syntax_exception.rs @@ -104,41 +104,81 @@ impl PatternSyntaxException { let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (description,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (description,), + ) .await?; if index >= 0 { let near_index = JavaLangString::from_rust_string(jvm, " near index ").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (near_index,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (near_index,), + ) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "append", "(I)Ljava/lang/StringBuffer;", (index,)) .await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "append", "(I)Ljava/lang/StringBuffer;", (index,)).await?; } let _: ClassInstanceRef = jvm .invoke_virtual( &buffer, + "java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (line_separator.clone(),), ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (pattern.clone(),)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (pattern.clone(),), + ) .await?; if index >= 0 { let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (line_separator,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (line_separator,), + ) .await?; for _ in 0..index { let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(C)Ljava/lang/StringBuffer;", (' ' as JavaChar,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(C)Ljava/lang/StringBuffer;", + (' ' as JavaChar,), + ) .await?; } let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(C)Ljava/lang/StringBuffer;", ('^' as JavaChar,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(C)Ljava/lang/StringBuffer;", + ('^' as JavaChar,), + ) .await?; } - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&buffer, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await } } diff --git a/java_runtime/src/classes/java/util/stack.rs b/java_runtime/src/classes/java/util/stack.rs index 81b2eb36..457031e5 100644 --- a/java_runtime/src/classes/java/util/stack.rs +++ b/java_runtime/src/classes/java/util/stack.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -15,15 +16,30 @@ impl Stack { parent_class: Some("java/util/Vector"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("empty", "()Z", Self::empty, Default::default()), - JavaMethodProto::new("peek", "()Ljava/lang/Object;", Self::peek, Default::default()), - JavaMethodProto::new("pop", "()Ljava/lang/Object;", Self::pop, Default::default()), - JavaMethodProto::new("push", "(Ljava/lang/Object;)Ljava/lang/Object;", Self::push, Default::default()), - JavaMethodProto::new("search", "(Ljava/lang/Object;)I", Self::search, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("empty", "()Z", Self::empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "peek", + "()Ljava/lang/Object;", + Self::peek, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "pop", + "()Ljava/lang/Object;", + Self::pop, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new("push", "(Ljava/lang/Object;)Ljava/lang/Object;", Self::push, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "search", + "(Ljava/lang/Object;)I", + Self::search, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -38,7 +54,7 @@ impl Stack { async fn empty(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { tracing::warn!("java.util.Stack::size({this:?})"); - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/Stack", "size", "()I", ()).await?; let is_empty = size == 0; Ok(is_empty) @@ -47,21 +63,25 @@ impl Stack { async fn peek(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::warn!("java.util.Stack::peek({this:?})"); - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/Stack", "size", "()I", ()).await?; if size == 0 { return Err(jvm.exception("java/util/EmptyStackException", "").await); } - let element = jvm.invoke_virtual(&this, "elementAt", "(I)Ljava/lang/Object;", (size - 1,)).await?; + let element = jvm + .invoke_virtual(&this, "java/util/Stack", "elementAt", "(I)Ljava/lang/Object;", (size - 1,)) + .await?; Ok(element) } async fn pop(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::warn!("java.util.Stack::pop({this:?})"); - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; - let element = jvm.invoke_virtual(&this, "peek", "()Ljava/lang/Object;", ()).await?; - let _: () = jvm.invoke_virtual(&this, "removeElementAt", "(I)V", (size - 1,)).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/Stack", "size", "()I", ()).await?; + let element = jvm.invoke_virtual(&this, "java/util/Stack", "peek", "()Ljava/lang/Object;", ()).await?; + let _: () = jvm + .invoke_virtual(&this, "java/util/Stack", "removeElementAt", "(I)V", (size - 1,)) + .await?; Ok(element) } @@ -75,7 +95,7 @@ impl Stack { tracing::warn!("java.util.Stack::push({this:?}, {element:?})"); let _: () = jvm - .invoke_virtual(&this, "addElement", "(Ljava/lang/Object;)V", (element.clone(),)) + .invoke_virtual(&this, "java/util/Stack", "addElement", "(Ljava/lang/Object;)V", (element.clone(),)) .await?; Ok(element) @@ -84,10 +104,12 @@ impl Stack { async fn search(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { tracing::warn!("java.util.Stack::search({this:?}, {element:?})"); - let i: i32 = jvm.invoke_virtual(&this, "lastIndexOf", "(Ljava/lang/Object;)I", (element,)).await?; + let i: i32 = jvm + .invoke_virtual(&this, "java/util/Stack", "lastIndexOf", "(Ljava/lang/Object;)I", (element,)) + .await?; if i >= 0 { - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "java/util/Stack", "size", "()I", ()).await?; Ok(size - i) } else { Ok(-1) diff --git a/java_runtime/src/classes/java/util/string_tokenizer.rs b/java_runtime/src/classes/java/util/string_tokenizer.rs index ae22d94c..94cdfc91 100644 --- a/java_runtime/src/classes/java/util/string_tokenizer.rs +++ b/java_runtime/src/classes/java/util/string_tokenizer.rs @@ -103,7 +103,7 @@ impl StringTokenizer { } let _: () = jvm.invoke_special(&this, "java/lang/Object", "", "()V", ()).await?; - let max_position: i32 = jvm.invoke_virtual(&string, "length", "()I", ()).await?; + let max_position: i32 = jvm.invoke_virtual(&string, "java/lang/String", "length", "()I", ()).await?; jvm.put_field(&mut this, "str", "Ljava/lang/String;", string).await?; jvm.put_field(&mut this, "delimiters", "Ljava/lang/String;", delimiters).await?; jvm.put_field(&mut this, "currentPosition", "I", 0).await?; @@ -140,7 +140,13 @@ impl StringTokenizer { }; let token: ClassInstanceRef = jvm - .invoke_virtual(&string, "substring", "(II)Ljava/lang/String;", (start as i32, end as i32)) + .invoke_virtual( + &string, + "java/lang/String", + "substring", + "(II)Ljava/lang/String;", + (start as i32, end as i32), + ) .await?; jvm.put_field(&mut this, "currentPosition", "I", end as i32).await?; Ok(token) @@ -155,7 +161,8 @@ impl StringTokenizer { tracing::debug!("java.util.StringTokenizer::nextToken({this:?}, {delimiters:?})"); jvm.put_field(&mut this, "delimiters", "Ljava/lang/String;", delimiters).await?; - jvm.invoke_virtual(&this, "nextToken", "()Ljava/lang/String;", ()).await + jvm.invoke_virtual(&this, "java/util/StringTokenizer", "nextToken", "()Ljava/lang/String;", ()) + .await } async fn count_tokens(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { @@ -175,11 +182,13 @@ impl StringTokenizer { } async fn has_more_elements(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - jvm.invoke_virtual(&this, "hasMoreTokens", "()Z", ()).await + jvm.invoke_virtual(&this, "java/util/StringTokenizer", "hasMoreTokens", "()Z", ()).await } async fn next_element(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { - let token: ClassInstanceRef = jvm.invoke_virtual(&this, "nextToken", "()Ljava/lang/String;", ()).await?; + let token: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/StringTokenizer", "nextToken", "()Ljava/lang/String;", ()) + .await?; Ok(ClassInstanceRef::new(token.instance)) } diff --git a/java_runtime/src/classes/java/util/time_zone.rs b/java_runtime/src/classes/java/util/time_zone.rs index b1f95d7d..94080f76 100644 --- a/java_runtime/src/classes/java/util/time_zone.rs +++ b/java_runtime/src/classes/java/util/time_zone.rs @@ -110,7 +110,9 @@ impl TimeZone { .await?; } - let cloned: ClassInstanceRef = jvm.invoke_virtual(&default, "clone", "()Ljava/lang/Object;", ()).await?; + let cloned: ClassInstanceRef = jvm + .invoke_virtual(&default, "java/lang/Object", "clone", "()Ljava/lang/Object;", ()) + .await?; Ok(ClassInstanceRef::new(cloned.instance)) } @@ -123,7 +125,9 @@ impl TimeZone { .await? .into() } else { - let cloned: ClassInstanceRef = jvm.invoke_virtual(&timezone, "clone", "()Ljava/lang/Object;", ()).await?; + let cloned: ClassInstanceRef = jvm + .invoke_virtual(&timezone, "java/lang/Object", "clone", "()Ljava/lang/Object;", ()) + .await?; ClassInstanceRef::new(cloned.instance) }; jvm.put_static_field("java/util/TimeZone", "defaultTimeZone", "Ljava/util/TimeZone;", stored) diff --git a/java_runtime/src/classes/java/util/timer.rs b/java_runtime/src/classes/java/util/timer.rs index cedf4013..f44876f2 100644 --- a/java_runtime/src/classes/java/util/timer.rs +++ b/java_runtime/src/classes/java/util/timer.rs @@ -66,7 +66,9 @@ impl Timer { .await?; jvm.put_field(&mut this, "thread", "Ljava/util/Timer$TimerThread;", timer_thread.clone()) .await?; - let _: () = jvm.invoke_virtual(&timer_thread, "start", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&timer_thread, "java/util/Timer$TimerThread", "start", "()V", ()) + .await?; Ok(()) } @@ -109,7 +111,7 @@ impl Timer { if date.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "time").await); } - let time: i64 = jvm.invoke_virtual(&date, "getTime", "()J", ()).await?; + let time: i64 = jvm.invoke_virtual(&date, "java/util/Date", "getTime", "()J", ()).await?; if time < 0 { return Err(jvm.exception("java/lang/IllegalArgumentException", "illegal execution time").await); } @@ -163,7 +165,7 @@ impl Timer { if period <= 0 { return Err(jvm.exception("java/lang/IllegalArgumentException", "non-positive period").await); } - let time: i64 = jvm.invoke_virtual(&date, "getTime", "()J", ()).await?; + let time: i64 = jvm.invoke_virtual(&date, "java/util/Date", "getTime", "()J", ()).await?; if time < 0 { return Err(jvm.exception("java/lang/IllegalArgumentException", "illegal execution time").await); } diff --git a/java_runtime/src/classes/java/util/timer_thread.rs b/java_runtime/src/classes/java/util/timer_thread.rs index 28ad1489..b75e5d4a 100644 --- a/java_runtime/src/classes/java/util/timer_thread.rs +++ b/java_runtime/src/classes/java/util/timer_thread.rs @@ -88,7 +88,7 @@ impl TimerThread { if !jvm.get_field::(this, "newTasksMayBeScheduled", "Z").await? { return Ok(WorkerAction::Stop); } - let wait_result: Result<()> = jvm.invoke_virtual(&queue, "wait", "()V", ()).await; + let wait_result: Result<()> = jvm.invoke_virtual(&queue, "java/lang/Object", "wait", "()V", ()).await; if let Err(error) = wait_result && !matches!( &error, @@ -165,7 +165,9 @@ impl TimerThread { if next_execution_time <= now { continue; } - let wait_result: Result<()> = jvm.invoke_virtual(&queue, "wait", "(J)V", (next_execution_time - now,)).await; + let wait_result: Result<()> = jvm + .invoke_virtual(&queue, "java/lang/Object", "wait", "(J)V", (next_execution_time - now,)) + .await; if let Err(error) = wait_result && !matches!( &error, @@ -193,7 +195,7 @@ impl TimerThread { match action { WorkerAction::Continue => {} WorkerAction::Run(task) => { - let _: () = jvm.invoke_virtual(&task, "run", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&task, "java/util/TimerTask", "run", "()V", ()).await?; } WorkerAction::Stop => return Ok(()), } diff --git a/java_runtime/src/classes/java/util/tree_map.rs b/java_runtime/src/classes/java/util/tree_map.rs index 9a708ff4..790014a4 100644 --- a/java_runtime/src/classes/java/util/tree_map.rs +++ b/java_runtime/src/classes/java/util/tree_map.rs @@ -108,7 +108,9 @@ impl TreeMap { if map.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "map").await); } - let comparator: ClassInstanceRef = jvm.invoke_virtual(&map, "comparator", "()Ljava/util/Comparator;", ()).await?; + let comparator: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "comparator", "()Ljava/util/Comparator;", ()) + .await?; let _: () = jvm .invoke_special(&this, "java/util/TreeMap", "", "(Ljava/util/Comparator;)V", (comparator,)) .await?; @@ -130,7 +132,8 @@ impl TreeMap { let equal = if value.is_null() { current.is_null() } else { - jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (current,)).await? + jvm.invoke_virtual(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) + .await? }; if equal { return Ok(true); @@ -383,14 +386,33 @@ impl TreeMap { } async fn copy_from_map(jvm: &Jvm, this: ClassInstanceRef, map: ClassInstanceRef) -> Result<()> { - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entry_set, "iterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&this, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &this, + "java/util/TreeMap", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } Ok(()) @@ -407,6 +429,7 @@ impl TreeMap { return jvm .invoke_virtual( &comparator, + &comparator.class_definition().name(), "compare", "(Ljava/lang/Object;Ljava/lang/Object;)I", (left.clone(), right.clone()), @@ -419,7 +442,14 @@ impl TreeMap { if !jvm.is_instance(left.as_ref(), "java/lang/Comparable") { return Err(jvm.exception("java/lang/ClassCastException", "key is not Comparable").await); } - jvm.invoke_virtual(left, "compareTo", "(Ljava/lang/Object;)I", (right.clone(),)).await + jvm.invoke_virtual( + left, + &left.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (right.clone(),), + ) + .await } pub(super) async fn find_entry( @@ -441,10 +471,12 @@ impl TreeMap { while !entry.is_null() { let stored_key: ClassInstanceRef = jvm.get_field(&entry, "key", "Ljava/lang/Object;").await?; let comparison: i32 = if comparator.is_null() { - jvm.invoke_virtual(key, "compareTo", "(Ljava/lang/Object;)I", (stored_key,)).await? + jvm.invoke_virtual(key, &key.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (stored_key,)) + .await? } else { jvm.invoke_virtual( &comparator, + &comparator.class_definition().name(), "compare", "(Ljava/lang/Object;Ljava/lang/Object;)I", (key.clone(), stored_key), diff --git a/java_runtime/src/classes/java/util/tree_map_entry.rs b/java_runtime/src/classes/java/util/tree_map_entry.rs index fcf633dd..629125b4 100644 --- a/java_runtime/src/classes/java/util/tree_map_entry.rs +++ b/java_runtime/src/classes/java/util/tree_map_entry.rs @@ -85,21 +85,27 @@ impl TreeMapEntry { } let key: ClassInstanceRef = jvm.get_field(&this, "key", "Ljava/lang/Object;").await?; - let other_key: ClassInstanceRef = jvm.invoke_virtual(&other, "getKey", "()Ljava/lang/Object;", ()).await?; + let other_key: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; let keys_equal = if key.is_null() { other_key.is_null() } else { - jvm.invoke_virtual(&key, "equals", "(Ljava/lang/Object;)Z", (other_key,)).await? + jvm.invoke_virtual(&key, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_key,)) + .await? }; if !keys_equal { return Ok(false); } let value: ClassInstanceRef = jvm.get_field(&this, "value", "Ljava/lang/Object;").await?; - let other_value: ClassInstanceRef = jvm.invoke_virtual(&other, "getValue", "()Ljava/lang/Object;", ()).await?; + let other_value: ClassInstanceRef = jvm + .invoke_virtual(&other, &other.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; if value.is_null() { Ok(other_value.is_null()) } else { - jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (other_value,)).await + jvm.invoke_virtual(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (other_value,)) + .await } } @@ -109,12 +115,12 @@ impl TreeMapEntry { let key_hash = if key.is_null() { 0 } else { - jvm.invoke_virtual(&key, "hashCode", "()I", ()).await? + jvm.invoke_virtual(&key, "java/lang/Object", "hashCode", "()I", ()).await? }; let value_hash = if value.is_null() { 0 } else { - jvm.invoke_virtual(&value, "hashCode", "()I", ()).await? + jvm.invoke_virtual(&value, "java/lang/Object", "hashCode", "()I", ()).await? }; Ok(key_hash ^ value_hash) } diff --git a/java_runtime/src/classes/java/util/tree_map_entry_set.rs b/java_runtime/src/classes/java/util/tree_map_entry_set.rs index 7f641e72..7b00222b 100644 --- a/java_runtime/src/classes/java/util/tree_map_entry_set.rs +++ b/java_runtime/src/classes/java/util/tree_map_entry_set.rs @@ -35,7 +35,7 @@ impl TreeMapEntrySet { async fn size(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "size", "()I", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, candidate: ClassInstanceRef) -> Result { @@ -43,19 +43,38 @@ impl TreeMapEntrySet { return Ok(false); } let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getValue", "()Ljava/lang/Object;", ()).await?; - let key: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getKey", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; if !jvm - .invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)) + .invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (key.clone(),), + ) .await? { return Ok(false); } - let stored: ClassInstanceRef = jvm.invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)).await?; + let stored: ClassInstanceRef = jvm + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) + .await?; if stored.is_null() { Ok(value.is_null()) } else { - jvm.invoke_virtual(&stored, "equals", "(Ljava/lang/Object;)Z", (value,)).await + jvm.invoke_virtual(&stored, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (value,)) + .await } } @@ -64,39 +83,62 @@ impl TreeMapEntrySet { return Ok(false); } let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getValue", "()Ljava/lang/Object;", ()).await?; - let key: ClassInstanceRef = jvm.invoke_virtual(&candidate, "getKey", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&candidate, &candidate.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; if !jvm - .invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)) + .invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (key.clone(),), + ) .await? { return Ok(false); } let stored: ClassInstanceRef = jvm - .invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),), + ) .await?; let equal = if stored.is_null() { value.is_null() } else { - jvm.invoke_virtual::<_, bool>(&stored, "equals", "(Ljava/lang/Object;)Z", (value,)) + jvm.invoke_virtual::<_, bool>(&stored, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (value,)) .await? }; if !equal { return Ok(false); } let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) .await?; Ok(true) } async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "entryIterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "entryIterator", "()Ljava/util/Iterator;", ()) + .await } } diff --git a/java_runtime/src/classes/java/util/tree_map_key_set.rs b/java_runtime/src/classes/java/util/tree_map_key_set.rs index 53ccb5c5..06f80239 100644 --- a/java_runtime/src/classes/java/util/tree_map_key_set.rs +++ b/java_runtime/src/classes/java/util/tree_map_key_set.rs @@ -35,35 +35,49 @@ impl TreeMapKeySet { async fn size(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "size", "()I", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, key: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (key,)).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "containsKey", "(Ljava/lang/Object;)Z", (key,)) + .await } async fn remove(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, key: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; if !jvm - .invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)) + .invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (key.clone(),), + ) .await? { return Ok(false); } let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) .await?; Ok(true) } async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "keyIterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "keyIterator", "()Ljava/util/Iterator;", ()) + .await } } diff --git a/java_runtime/src/classes/java/util/tree_map_sub_map.rs b/java_runtime/src/classes/java/util/tree_map_sub_map.rs index 82e0bd4a..1feb81e7 100644 --- a/java_runtime/src/classes/java/util/tree_map_sub_map.rs +++ b/java_runtime/src/classes/java/util/tree_map_sub_map.rs @@ -112,10 +112,17 @@ impl TreeMapSubMap { } async fn size(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { - let iterator: ClassInstanceRef = jvm.invoke_virtual(&this, "entryIterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/TreeMap$SubMap", "entryIterator", "()Ljava/util/Iterator;", ()) + .await?; let mut size = 0; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; size += 1; } Ok(size) @@ -130,13 +137,21 @@ impl TreeMapSubMap { } async fn contains_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result { - let iterator: ClassInstanceRef = jvm.invoke_virtual(&this, "valueIterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let current: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/TreeMap$SubMap", "valueIterator", "()Ljava/util/Iterator;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let current: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let equal = if value.is_null() { current.is_null() } else { - jvm.invoke_virtual(&value, "equals", "(Ljava/lang/Object;)Z", (current,)).await? + jvm.invoke_virtual(&value, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (current,)) + .await? }; if equal { return Ok(true); @@ -168,8 +183,14 @@ impl TreeMapSubMap { return Err(jvm.exception("java/lang/IllegalArgumentException", "key outside range").await); } let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/TreeMap;").await?; - jvm.invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) - .await + jvm.invoke_virtual( + &map, + "java/util/TreeMap", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) + .await } async fn remove( @@ -182,21 +203,32 @@ impl TreeMapSubMap { return Ok(None.into()); } let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/TreeMap;").await?; - jvm.invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)).await + jvm.invoke_virtual(&map, "java/util/TreeMap", "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .await } async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { - let iterator: ClassInstanceRef = jvm.invoke_virtual(&this, "entryIterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&this, "java/util/TreeMap$SubMap", "entryIterator", "()Ljava/util/Iterator;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; } Ok(()) } async fn comparator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/TreeMap;").await?; - jvm.invoke_virtual(&map, "comparator", "()Ljava/util/Comparator;", ()).await + jvm.invoke_virtual(&map, "java/util/TreeMap", "comparator", "()Ljava/util/Comparator;", ()) + .await } async fn first_key(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { diff --git a/java_runtime/src/classes/java/util/tree_map_values.rs b/java_runtime/src/classes/java/util/tree_map_values.rs index 7a4f72bc..ee6a64bb 100644 --- a/java_runtime/src/classes/java/util/tree_map_values.rs +++ b/java_runtime/src/classes/java/util/tree_map_values.rs @@ -35,26 +35,37 @@ impl TreeMapValues { async fn size(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "size", "()I", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "containsValue", "(Ljava/lang/Object;)Z", (value,)).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "containsValue", "(Ljava/lang/Object;)Z", (value,)) + .await } async fn remove(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&map, "valueIterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let current: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "valueIterator", "()Ljava/util/Iterator;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let current: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let equal = if current.is_null() { value.is_null() } else { - jvm.invoke_virtual(¤t, "equals", "(Ljava/lang/Object;)Z", (value.clone(),)).await? + jvm.invoke_virtual(¤t, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (value.clone(),)) + .await? }; if equal { - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; return Ok(true); } } @@ -63,11 +74,12 @@ impl TreeMapValues { async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "map", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "valueIterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "valueIterator", "()Ljava/util/Iterator;", ()) + .await } } diff --git a/java_runtime/src/classes/java/util/tree_set.rs b/java_runtime/src/classes/java/util/tree_set.rs index 1c36b437..9061fd0f 100644 --- a/java_runtime/src/classes/java/util/tree_set.rs +++ b/java_runtime/src/classes/java/util/tree_set.rs @@ -89,7 +89,9 @@ impl TreeSet { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } let _: () = jvm.invoke_special(&this, "java/util/TreeSet", "", "()V", ()).await?; - let _: bool = jvm.invoke_virtual(&this, "addAll", "(Ljava/util/Collection;)Z", (collection,)).await?; + let _: bool = jvm + .invoke_virtual(&this, "java/util/TreeSet", "addAll", "(Ljava/util/Collection;)Z", (collection,)) + .await?; Ok(()) } @@ -97,11 +99,15 @@ impl TreeSet { if set.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "set").await); } - let comparator: ClassInstanceRef = jvm.invoke_virtual(&set, "comparator", "()Ljava/util/Comparator;", ()).await?; + let comparator: ClassInstanceRef = jvm + .invoke_virtual(&set, &set.class_definition().name(), "comparator", "()Ljava/util/Comparator;", ()) + .await?; let _: () = jvm .invoke_special(&this, "java/util/TreeSet", "", "(Ljava/util/Comparator;)V", (comparator,)) .await?; - let _: bool = jvm.invoke_virtual(&this, "addAll", "(Ljava/util/Collection;)Z", (set,)).await?; + let _: bool = jvm + .invoke_virtual(&this, "java/util/TreeSet", "addAll", "(Ljava/util/Collection;)Z", (set,)) + .await?; Ok(()) } @@ -115,12 +121,13 @@ impl TreeSet { async fn size(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "size", "()I", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "size", "()I", ()).await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (element,)).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "containsKey", "(Ljava/lang/Object;)Z", (element,)) + .await } async fn add(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { @@ -129,6 +136,7 @@ impl TreeSet { let old: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (element, present), @@ -140,41 +148,59 @@ impl TreeSet { async fn remove(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; if !jvm - .invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (element.clone(),)) + .invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (element.clone(),), + ) .await? { return Ok(false); } let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (element,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (element,), + ) .await?; Ok(true) } async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "clear", "()V", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "clear", "()V", ()).await } async fn iterator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; - let keys: ClassInstanceRef = jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await?; - jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await + let keys: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + jvm.invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await } async fn comparator(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "comparator", "()Ljava/util/Comparator;", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "comparator", "()Ljava/util/Comparator;", ()) + .await } async fn first(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "firstKey", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "firstKey", "()Ljava/lang/Object;", ()) + .await } async fn last(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; - jvm.invoke_virtual(&map, "lastKey", "()Ljava/lang/Object;", ()).await + jvm.invoke_virtual(&map, &map.class_definition().name(), "lastKey", "()Ljava/lang/Object;", ()) + .await } async fn sub_set( @@ -186,7 +212,13 @@ impl TreeSet { ) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; let range: ClassInstanceRef = jvm - .invoke_virtual(&map, "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (from, to)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "subMap", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", + (from, to), + ) .await?; Ok(jvm.new_class("java/util/TreeSet", "(Ljava/util/SortedMap;)V", (range,)).await?.into()) } @@ -199,7 +231,13 @@ impl TreeSet { ) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; let range: ClassInstanceRef = jvm - .invoke_virtual(&map, "headMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (to,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "headMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (to,), + ) .await?; Ok(jvm.new_class("java/util/TreeSet", "(Ljava/util/SortedMap;)V", (range,)).await?.into()) } @@ -212,7 +250,13 @@ impl TreeSet { ) -> Result> { let map: ClassInstanceRef = jvm.get_field(&this, "m", "Ljava/util/SortedMap;").await?; let range: ClassInstanceRef = jvm - .invoke_virtual(&map, "tailMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (from,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "tailMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (from,), + ) .await?; Ok(jvm.new_class("java/util/TreeSet", "(Ljava/util/SortedMap;)V", (range,)).await?.into()) } diff --git a/java_runtime/src/classes/java/util/vector.rs b/java_runtime/src/classes/java/util/vector.rs index 8cfd94e5..fcf8c764 100644 --- a/java_runtime/src/classes/java/util/vector.rs +++ b/java_runtime/src/classes/java/util/vector.rs @@ -24,19 +24,34 @@ impl Vector { parent_class: Some("java/util/AbstractList"), interfaces: vec!["java/util/List", "java/lang/Cloneable", "java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(I)V", Self::init_with_capacity, Default::default()), - JavaMethodProto::new("", "(II)V", Self::init_with_capacity_increment, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(I)V", Self::init_with_capacity, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(II)V", Self::init_with_capacity_increment, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/util/Collection;)V", Self::init_from_collection, MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("capacity", "()I", Self::capacity, Default::default()), - JavaMethodProto::new("copyInto", "([Ljava/lang/Object;)V", Self::copy_into, Default::default()), - JavaMethodProto::new("elements", "()Ljava/util/Enumeration;", Self::elements, Default::default()), - JavaMethodProto::new("ensureCapacity", "(I)V", Self::ensure_capacity_api, Default::default()), + JavaMethodProto::new( + "capacity", + "()I", + Self::capacity, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "copyInto", + "([Ljava/lang/Object;)V", + Self::copy_into, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new("elements", "()Ljava/util/Enumeration;", Self::elements, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "ensureCapacity", + "(I)V", + Self::ensure_capacity_api, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), JavaMethodProto::new( "add", "(Ljava/lang/Object;)Z", @@ -49,9 +64,24 @@ impl Vector { Self::add_at, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), - JavaMethodProto::new("addElement", "(Ljava/lang/Object;)V", Self::add_element, Default::default()), - JavaMethodProto::new("insertElementAt", "(Ljava/lang/Object;I)V", Self::insert_element_at, Default::default()), - JavaMethodProto::new("elementAt", "(I)Ljava/lang/Object;", Self::element_at, Default::default()), + JavaMethodProto::new( + "addElement", + "(Ljava/lang/Object;)V", + Self::add_element, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "insertElementAt", + "(Ljava/lang/Object;I)V", + Self::insert_element_at, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "elementAt", + "(I)Ljava/lang/Object;", + Self::element_at, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), JavaMethodProto::new( "get", "(I)Ljava/lang/Object;", @@ -65,28 +95,88 @@ impl Vector { MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), + JavaMethodProto::new( + "isEmpty", + "()Z", + Self::is_empty, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), JavaMethodProto::new( "remove", "(I)Ljava/lang/Object;", Self::remove, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), - JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove_object, Default::default()), - JavaMethodProto::new("removeAllElements", "()V", Self::remove_all_elements, Default::default()), - JavaMethodProto::new("removeElementAt", "(I)V", Self::remove_element_at, Default::default()), - JavaMethodProto::new("indexOf", "(Ljava/lang/Object;)I", Self::index_of, Default::default()), - JavaMethodProto::new("indexOf", "(Ljava/lang/Object;I)I", Self::index_of_from, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), - JavaMethodProto::new("lastIndexOf", "(Ljava/lang/Object;)I", Self::last_index_of, Default::default()), - JavaMethodProto::new("lastIndexOf", "(Ljava/lang/Object;I)I", Self::last_index_of_index, Default::default()), - JavaMethodProto::new("firstElement", "()Ljava/lang/Object;", Self::first_element, Default::default()), - JavaMethodProto::new("lastElement", "()Ljava/lang/Object;", Self::last_element, Default::default()), - JavaMethodProto::new("setElementAt", "(Ljava/lang/Object;I)V", Self::set_element_at, Default::default()), - JavaMethodProto::new("setSize", "(I)V", Self::set_size, Default::default()), - JavaMethodProto::new("removeElement", "(Ljava/lang/Object;)Z", Self::remove_element, Default::default()), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("toArray", "()[Ljava/lang/Object;", Self::to_array, Default::default()), + JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove_object, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "removeAllElements", + "()V", + Self::remove_all_elements, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "removeElementAt", + "(I)V", + Self::remove_element_at, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new("indexOf", "(Ljava/lang/Object;)I", Self::index_of, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "indexOf", + "(Ljava/lang/Object;I)I", + Self::index_of_from, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "lastIndexOf", + "(Ljava/lang/Object;)I", + Self::last_index_of, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "lastIndexOf", + "(Ljava/lang/Object;I)I", + Self::last_index_of_index, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "firstElement", + "()Ljava/lang/Object;", + Self::first_element, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "lastElement", + "()Ljava/lang/Object;", + Self::last_element, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "setElementAt", + "(Ljava/lang/Object;I)V", + Self::set_element_at, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "setSize", + "(I)V", + Self::set_size, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "removeElement", + "(Ljava/lang/Object;)Z", + Self::remove_element, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "toArray", + "()[Ljava/lang/Object;", + Self::to_array, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), JavaMethodProto::new( "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", @@ -141,8 +231,18 @@ impl Vector { Self::list_iterator_at, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, ), - JavaMethodProto::new("trimToSize", "()V", Self::trim_to_size, Default::default()), - JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, Default::default()), + JavaMethodProto::new( + "trimToSize", + "()V", + Self::trim_to_size, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new( + "toString", + "()Ljava/lang/String;", + Self::to_string, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), ], fields: vec![ JavaFieldProto::new("elementData", "[Ljava/lang/Object;", FieldAccessFlags::PROTECTED), @@ -205,9 +305,13 @@ impl Vector { if collection.is_null() { return Err(jvm.exception("java/lang/NullPointerException", "collection").await); } - let size: i32 = jvm.invoke_virtual(&collection, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&collection, &collection.class_definition().name(), "size", "()I", ()) + .await?; let _: () = jvm.invoke_special(&this, "java/util/Vector", "", "(I)V", (size,)).await?; - let _: bool = jvm.invoke_virtual(&this, "addAll", "(Ljava/util/Collection;)Z", (collection,)).await?; + let _: bool = jvm + .invoke_virtual(&this, "java/util/Vector", "addAll", "(Ljava/util/Collection;)Z", (collection,)) + .await?; Ok(()) } @@ -238,7 +342,9 @@ impl Vector { async fn elements(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("java.util.Vector::elements({this:?})"); - let snapshot: ClassInstanceRef> = jvm.invoke_virtual(&this, "toArray", "()[Ljava/lang/Object;", ()).await?; + let snapshot: ClassInstanceRef> = jvm + .invoke_virtual(&this, "java/util/Vector", "toArray", "()[Ljava/lang/Object;", ()) + .await?; Ok(jvm .new_class("java/util/Hashtable$Enumerator", "([Ljava/lang/Object;)V", (snapshot,)) .await? @@ -278,7 +384,7 @@ impl Vector { .await); } - jvm.invoke_virtual(&this, "insertElementAt", "(Ljava/lang/Object;I)V", (element, index)) + jvm.invoke_virtual(&this, "java/util/Vector", "insertElementAt", "(Ljava/lang/Object;I)V", (element, index)) .await } @@ -345,7 +451,8 @@ impl Vector { async fn get(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, index: i32) -> Result> { tracing::debug!("java.util.Vector::get({this:?}, {index:?})"); - jvm.invoke_virtual(&this, "elementAt", "(I)Ljava/lang/Object;", (index,)).await + jvm.invoke_virtual(&this, "java/util/Vector", "elementAt", "(I)Ljava/lang/Object;", (index,)) + .await } async fn set( @@ -415,7 +522,8 @@ impl Vector { async fn remove_object(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { tracing::debug!("java.util.Vector::remove({this:?}, {element:?})"); - jvm.invoke_virtual(&this, "removeElement", "(Ljava/lang/Object;)Z", (element,)).await + jvm.invoke_virtual(&this, "java/util/Vector", "removeElement", "(Ljava/lang/Object;)Z", (element,)) + .await } async fn remove_all_elements(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result<()> { @@ -463,7 +571,8 @@ impl Vector { async fn index_of(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { tracing::debug!("java.util.Vector::indexOf({this:?}, {element:?})"); - jvm.invoke_virtual(&this, "indexOf", "(Ljava/lang/Object;I)I", (element, 0)).await + jvm.invoke_virtual(&this, "java/util/Vector", "indexOf", "(Ljava/lang/Object;I)I", (element, 0)) + .await } async fn index_of_from( @@ -504,7 +613,9 @@ impl Vector { async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { tracing::debug!("java.util.Vector::contains({this:?}, {element:?})"); - let index: i32 = jvm.invoke_virtual(&this, "indexOf", "(Ljava/lang/Object;)I", (element,)).await?; + let index: i32 = jvm + .invoke_virtual(&this, "java/util/Vector", "indexOf", "(Ljava/lang/Object;)I", (element,)) + .await?; Ok(index >= 0) } @@ -515,7 +626,13 @@ impl Vector { let element_count: i32 = jvm.get_field(&this, "elementCount", "I").await?; let index: i32 = jvm - .invoke_virtual(&this, "lastIndexOf", "(Ljava/lang/Object;I)I", (element, element_count - 1)) + .invoke_virtual( + &this, + "java/util/Vector", + "lastIndexOf", + "(Ljava/lang/Object;I)I", + (element, element_count - 1), + ) .await?; Ok(index) @@ -599,7 +716,13 @@ impl Vector { ) -> Result<()> { tracing::debug!("java.util.Vector::setElementAt({this:?}, {element:?}, {index:?})"); let _: ClassInstanceRef = jvm - .invoke_virtual(&this, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (index, element)) + .invoke_virtual( + &this, + "java/util/Vector", + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (index, element), + ) .await?; Ok(()) } @@ -625,10 +748,12 @@ impl Vector { async fn remove_element(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, element: ClassInstanceRef) -> Result { tracing::debug!("java.util.Vector::removeElement({this:?}, {element:?})"); - let index: i32 = jvm.invoke_virtual(&this, "indexOf", "(Ljava/lang/Object;)I", (element,)).await?; + let index: i32 = jvm + .invoke_virtual(&this, "java/util/Vector", "indexOf", "(Ljava/lang/Object;)I", (element,)) + .await?; if index >= 0 { - let _: () = jvm.invoke_virtual(&this, "removeElementAt", "(I)V", (index,)).await?; + let _: () = jvm.invoke_virtual(&this, "java/util/Vector", "removeElementAt", "(I)V", (index,)).await?; Ok(true) } else { Ok(false) @@ -638,7 +763,7 @@ impl Vector { async fn clear(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { tracing::debug!("java.util.Vector::clear({this:?})"); - jvm.invoke_virtual(&this, "removeAllElements", "()V", ()).await + jvm.invoke_virtual(&this, "java/util/Vector", "removeAllElements", "()V", ()).await } async fn to_array(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result>> { @@ -791,7 +916,9 @@ impl Vector { } else if element.instance.as_ref().unwrap().equals(&**this)? { result.push_str("(this Collection)"); } else { - let text: ClassInstanceRef = jvm.invoke_virtual(&element, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&element, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; result.push_str(&JavaLangString::to_rust_string(jvm, &text).await?); } } @@ -833,7 +960,8 @@ impl Vector { return Ok(false); } - jvm.invoke_virtual(left, "equals", "(Ljava/lang/Object;)Z", (right.clone(),)).await + jvm.invoke_virtual(left, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) + .await } async fn copy_to_array(jvm: &Jvm, source: &ClassInstanceRef>, len: i32) -> Result>> { diff --git a/java_runtime/src/classes/java/util/vector_itr.rs b/java_runtime/src/classes/java/util/vector_itr.rs index 5970e2da..cd42fb34 100644 --- a/java_runtime/src/classes/java/util/vector_itr.rs +++ b/java_runtime/src/classes/java/util/vector_itr.rs @@ -50,7 +50,7 @@ impl VectorItr { } async fn init(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, list: ClassInstanceRef, index: i32) -> Result<()> { - let size: i32 = jvm.invoke_virtual(&list, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&list, "java/util/Vector", "size", "()I", ()).await?; if index < 0 || index > size { return Err(jvm.exception("java/lang/IndexOutOfBoundsException", "list iterator index").await); } @@ -63,16 +63,18 @@ impl VectorItr { async fn has_next(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/Vector;").await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; - Ok(cursor < jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?) + Ok(cursor < jvm.invoke_virtual::<_, i32>(&list, "java/util/Vector", "size", "()I", ()).await?) } async fn next(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result> { let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/Vector;").await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; - if cursor >= jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await? { + if cursor >= jvm.invoke_virtual::<_, i32>(&list, "java/util/Vector", "size", "()I", ()).await? { return Err(jvm.exception("java/util/NoSuchElementException", "Vector iterator exhausted").await); } - let element = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (cursor,)).await?; + let element = jvm + .invoke_virtual(&list, "java/util/Vector", "get", "(I)Ljava/lang/Object;", (cursor,)) + .await?; jvm.put_field(&mut this, "cursor", "I", cursor + 1).await?; jvm.put_field(&mut this, "lastReturned", "I", cursor).await?; Ok(element) @@ -89,7 +91,9 @@ impl VectorItr { } let index = cursor - 1; let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/Vector;").await?; - let element = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (index,)).await?; + let element = jvm + .invoke_virtual(&list, "java/util/Vector", "get", "(I)Ljava/lang/Object;", (index,)) + .await?; jvm.put_field(&mut this, "cursor", "I", index).await?; jvm.put_field(&mut this, "lastReturned", "I", index).await?; Ok(element) @@ -109,7 +113,9 @@ impl VectorItr { return Err(jvm.exception("java/lang/IllegalStateException", "iterator state").await); } let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/Vector;").await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&list, "remove", "(I)Ljava/lang/Object;", (last_returned,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&list, "java/util/Vector", "remove", "(I)Ljava/lang/Object;", (last_returned,)) + .await?; let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; if last_returned < cursor { jvm.put_field(&mut this, "cursor", "I", cursor - 1).await?; @@ -124,7 +130,13 @@ impl VectorItr { } let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/Vector;").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (last_returned, element)) + .invoke_virtual( + &list, + "java/util/Vector", + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (last_returned, element), + ) .await?; Ok(()) } @@ -132,7 +144,9 @@ impl VectorItr { async fn add(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, element: ClassInstanceRef) -> Result<()> { let cursor: i32 = jvm.get_field(&this, "cursor", "I").await?; let list: ClassInstanceRef = jvm.get_field(&this, "list", "Ljava/util/Vector;").await?; - let _: () = jvm.invoke_virtual(&list, "add", "(ILjava/lang/Object;)V", (cursor, element)).await?; + let _: () = jvm + .invoke_virtual(&list, "java/util/Vector", "add", "(ILjava/lang/Object;)V", (cursor, element)) + .await?; jvm.put_field(&mut this, "cursor", "I", cursor + 1).await?; jvm.put_field(&mut this, "lastReturned", "I", -1).await } diff --git a/java_runtime/src/classes/java/util/zip/zip_file.rs b/java_runtime/src/classes/java/util/zip/zip_file.rs index 23498a4d..0257d547 100644 --- a/java_runtime/src/classes/java/util/zip/zip_file.rs +++ b/java_runtime/src/classes/java/util/zip/zip_file.rs @@ -8,6 +8,7 @@ use std::io::{Cursor, Read}; use zip::ZipArchive; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -29,23 +30,23 @@ impl ZipFile { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/File;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/io/File;)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "getEntry", "(Ljava/lang/String;)Ljava/util/zip/ZipEntry;", Self::get_entry, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "getInputStream", "(Ljava/util/zip/ZipEntry;)Ljava/io/InputStream;", Self::get_input_stream, - Default::default(), + MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("entries", "()Ljava/util/Enumeration;", Self::entries, Default::default()), + JavaMethodProto::new("entries", "()Ljava/util/Enumeration;", Self::entries, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("zipData", "[B", Default::default())], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } @@ -66,11 +67,11 @@ impl ZipFile { let _: () = jvm.invoke_special(&this, "java/lang/Object", "", "()V", ()).await?; - let length: i64 = jvm.invoke_virtual(&file, "length", "()J", ()).await?; + let length: i64 = jvm.invoke_virtual(&file, "java/io/File", "length", "()J", ()).await?; let is = jvm.new_class("java/io/FileInputStream", "(Ljava/io/File;)V", (file,)).await?; let buf = jvm.instantiate_array("B", length as _).await?; - let _: i32 = jvm.invoke_virtual(&is, "read", "([B)I", (buf.clone(),)).await?; + let _: i32 = jvm.invoke_virtual(&is, "java/io/InputStream", "read", "([B)I", (buf.clone(),)).await?; jvm.put_field(&mut this, "zipData", "[B", buf).await?; @@ -95,7 +96,9 @@ impl ZipFile { let file_size = zip.by_name(&name).map(|x| x.size()); if let Ok(x) = file_size { - let _: () = jvm.invoke_virtual(&entry, "setSize", "(J)V", (x as i64,)).await?; + let _: () = jvm + .invoke_virtual(&entry, "java/util/zip/ZipEntry", "setSize", "(J)V", (x as i64,)) + .await?; Ok(entry.into()) } else { @@ -134,7 +137,9 @@ impl ZipFile { ) -> Result> { tracing::debug!("java.util.zip.ZipFile::getInputStream({this:?}, {entry:?})"); - let entry_name = jvm.invoke_virtual(&entry, "getName", "()Ljava/lang/String;", ()).await?; + let entry_name = jvm + .invoke_virtual(&entry, "java/util/zip/ZipEntry", "getName", "()Ljava/lang/String;", ()) + .await?; let entry_name = JavaLangString::to_rust_string(jvm, &entry_name).await?; let data = { diff --git a/java_runtime/src/classes/java/util/zip/zip_file_entries.rs b/java_runtime/src/classes/java/util/zip/zip_file_entries.rs index 0e518fdc..03379872 100644 --- a/java_runtime/src/classes/java/util/zip/zip_file_entries.rs +++ b/java_runtime/src/classes/java/util/zip/zip_file_entries.rs @@ -71,7 +71,13 @@ impl ZipFileEntries { let zip_file = jvm.get_field(&this, "zipFile", "Ljava/util/zip/ZipFile;").await?; let entry = jvm - .invoke_virtual(&zip_file, "getEntry", "(Ljava/lang/String;)Ljava/util/zip/ZipEntry;", (name[0].clone(),)) + .invoke_virtual( + &zip_file, + "java/util/zip/ZipFile", + "getEntry", + "(Ljava/lang/String;)Ljava/util/zip/ZipEntry;", + (name[0].clone(),), + ) .await?; jvm.put_field(&mut this, "i", "I", i + 1).await?; diff --git a/java_runtime/src/classes/org/rustjava/lang/rust_jar_class_loader.rs b/java_runtime/src/classes/org/rustjava/lang/rust_jar_class_loader.rs index 28a5274b..24af72e5 100644 --- a/java_runtime/src/classes/org/rustjava/lang/rust_jar_class_loader.rs +++ b/java_runtime/src/classes/org/rustjava/lang/rust_jar_class_loader.rs @@ -1,6 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::MethodAccessFlags; use jvm::{Array, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -18,8 +19,18 @@ impl RustJarClassLoader { parent_class: Some("java/lang/ClassLoader"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "([Ljava/lang/String;Ljava/lang/ClassLoader;)V", Self::init, Default::default()), - JavaMethodProto::new("findClass", "(Ljava/lang/String;)Ljava/lang/Class;", Self::find_class, Default::default()), + JavaMethodProto::new( + "", + "([Ljava/lang/String;Ljava/lang/ClassLoader;)V", + Self::init, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new( + "findClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + Self::find_class, + MethodAccessFlags::PROTECTED, + ), ], fields: vec![JavaFieldProto::new("classPaths", "[Ljava/lang/String;", Default::default())], access_flags: Default::default(), diff --git a/java_runtime/src/classes/org/rustjava/net/file_url_connection.rs b/java_runtime/src/classes/org/rustjava/net/file_url_connection.rs index 9a30c528..7e205c79 100644 --- a/java_runtime/src/classes/org/rustjava/net/file_url_connection.rs +++ b/java_runtime/src/classes/org/rustjava/net/file_url_connection.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::MethodAccessFlags; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -22,7 +23,12 @@ impl FileURLConnection { interfaces: vec![], methods: vec![ JavaMethodProto::new("", "(Ljava/net/URL;Ljava/io/File;)V", Self::init, Default::default()), - JavaMethodProto::new("getInputStream", "()Ljava/io/InputStream;", Self::get_input_stream, Default::default()), + JavaMethodProto::new( + "getInputStream", + "()Ljava/io/InputStream;", + Self::get_input_stream, + MethodAccessFlags::PUBLIC, + ), ], fields: vec![JavaFieldProto::new("file", "Ljava/io/File;", Default::default())], access_flags: Default::default(), diff --git a/java_runtime/src/classes/org/rustjava/net/file_url_handler.rs b/java_runtime/src/classes/org/rustjava/net/file_url_handler.rs index 08e86077..125125f1 100644 --- a/java_runtime/src/classes/org/rustjava/net/file_url_handler.rs +++ b/java_runtime/src/classes/org/rustjava/net/file_url_handler.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::MethodAccessFlags; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -26,7 +27,7 @@ impl FileURLHandler { "openConnection", "(Ljava/net/URL;)Ljava/net/URLConnection;", Self::open_connection, - Default::default(), + MethodAccessFlags::PROTECTED, ), ], fields: vec![], @@ -50,7 +51,7 @@ impl FileURLHandler { ) -> Result> { tracing::debug!("org.rustjava.net.FileURLHandler::openConnection({this:?}, {url:?})"); - let file: ClassInstanceRef = jvm.invoke_virtual(&url, "getFile", "()Ljava/lang/String;", ()).await?; + let file: ClassInstanceRef = jvm.invoke_virtual(&url, "java/net/URL", "getFile", "()Ljava/lang/String;", ()).await?; let file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (file,)).await?; let connection = jvm diff --git a/java_runtime/src/classes/org/rustjava/net/jar_url_connection.rs b/java_runtime/src/classes/org/rustjava/net/jar_url_connection.rs index 3738e66b..17d6faa8 100644 --- a/java_runtime/src/classes/org/rustjava/net/jar_url_connection.rs +++ b/java_runtime/src/classes/org/rustjava/net/jar_url_connection.rs @@ -26,8 +26,13 @@ impl JarURLConnection { methods: vec![ JavaMethodProto::new("", "()V", Self::clinit, MethodAccessFlags::STATIC), JavaMethodProto::new("", "(Ljava/net/URL;)V", Self::init, Default::default()), - JavaMethodProto::new("getJarFile", "()Ljava/util/jar/JarFile;", Self::get_jar_file, Default::default()), - JavaMethodProto::new("getInputStream", "()Ljava/io/InputStream;", Self::get_input_stream, Default::default()), + JavaMethodProto::new("getJarFile", "()Ljava/util/jar/JarFile;", Self::get_jar_file, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "getInputStream", + "()Ljava/io/InputStream;", + Self::get_input_stream, + MethodAccessFlags::PUBLIC, + ), ], fields: vec![JavaFieldProto::new("openedFiles", "Ljava/util/Hashtable;", FieldAccessFlags::STATIC)], access_flags: Default::default(), @@ -57,18 +62,28 @@ impl JarURLConnection { async fn get_jar_file(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("org.rustjava.net.JarURLConnection::getJarFile({this:?})"); - let url = jvm.invoke_virtual(&this, "getJarFileURL", "()Ljava/net/URL;", ()).await?; - let protocol = jvm.invoke_virtual(&url, "getProtocol", "()Ljava/lang/String;", ()).await?; + let url = jvm + .invoke_virtual(&this, "org/rustjava/net/JarURLConnection", "getJarFileURL", "()Ljava/net/URL;", ()) + .await?; + let protocol = jvm + .invoke_virtual(&url, "java/net/URL", "getProtocol", "()Ljava/lang/String;", ()) + .await?; let protocol = JavaLangString::to_rust_string(jvm, &protocol).await?; if protocol == "file" { - let name: ClassInstanceRef = jvm.invoke_virtual(&url, "getFile", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm.invoke_virtual(&url, "java/net/URL", "getFile", "()Ljava/lang/String;", ()).await?; let opened_files = jvm .get_static_field("org/rustjava/net/JarURLConnection", "openedFiles", "Ljava/util/Hashtable;") .await?; let cache: ClassInstanceRef = jvm - .invoke_virtual(&opened_files, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (name.clone(),)) + .invoke_virtual( + &opened_files, + "java/util/Hashtable", + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (name.clone(),), + ) .await?; if !cache.is_null() { @@ -80,6 +95,7 @@ impl JarURLConnection { let _: ClassInstanceRef = jvm .invoke_virtual( &opened_files, + "java/util/Hashtable", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (name, jar_file.clone()), @@ -96,11 +112,21 @@ impl JarURLConnection { async fn get_input_stream(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result> { tracing::debug!("org.rustjava.net.JarURLConnection::getInputStream({this:?})"); - let entry: ClassInstanceRef = jvm.invoke_virtual(&this, "getEntryName", "()Ljava/lang/String;", ()).await?; - let jar_file = jvm.invoke_virtual(&this, "getJarFile", "()Ljava/util/jar/JarFile;", ()).await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual(&this, "org/rustjava/net/JarURLConnection", "getEntryName", "()Ljava/lang/String;", ()) + .await?; + let jar_file = jvm + .invoke_virtual(&this, "org/rustjava/net/JarURLConnection", "getJarFile", "()Ljava/util/jar/JarFile;", ()) + .await?; let jar_entry: ClassInstanceRef = jvm - .invoke_virtual(&jar_file, "getJarEntry", "(Ljava/lang/String;)Ljava/util/jar/JarEntry;", (entry,)) + .invoke_virtual( + &jar_file, + "java/util/jar/JarFile", + "getJarEntry", + "(Ljava/lang/String;)Ljava/util/jar/JarEntry;", + (entry,), + ) .await?; if jar_entry.is_null() { @@ -110,6 +136,7 @@ impl JarURLConnection { let jar_input_stream = jvm .invoke_virtual( &jar_file, + "java/util/jar/JarFile", "getInputStream", "(Ljava/util/zip/ZipEntry;)Ljava/io/InputStream;", (jar_entry,), diff --git a/java_runtime/src/classes/org/rustjava/net/jar_url_handler.rs b/java_runtime/src/classes/org/rustjava/net/jar_url_handler.rs index bd3f0480..c2a29e5f 100644 --- a/java_runtime/src/classes/org/rustjava/net/jar_url_handler.rs +++ b/java_runtime/src/classes/org/rustjava/net/jar_url_handler.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::MethodAccessFlags; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -23,7 +24,7 @@ impl JarURLHandler { "openConnection", "(Ljava/net/URL;)Ljava/net/URLConnection;", Self::open_connection, - Default::default(), + MethodAccessFlags::PROTECTED, ), ], fields: vec![], diff --git a/java_runtime/tests/classes/java/io/test_buffered_reader.rs b/java_runtime/tests/classes/java/io/test_buffered_reader.rs index 44705650..927a81ba 100644 --- a/java_runtime/tests/classes/java/io/test_buffered_reader.rs +++ b/java_runtime/tests/classes/java/io/test_buffered_reader.rs @@ -156,7 +156,7 @@ impl ReadRunner { async fn run(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result<()> { jvm.put_field(&mut this, "started", "Z", true).await?; let reader: ClassInstanceRef = jvm.get_field(&this, "reader", "Ljava/io/BufferedReader;").await?; - let value: i32 = jvm.invoke_virtual(&reader, "read", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "read", "()I", ()).await?; jvm.put_field(&mut this, "value", "I", value).await?; jvm.put_field(&mut this, "done", "Z", true).await?; Ok(()) @@ -205,39 +205,67 @@ async fn test_buffered_reader_constructors_and_read_contract() -> Result<()> { let mut chars = jvm.instantiate_array("C", 4).await?; jvm.store_array(&mut chars, 0, ['?' as JavaChar; 4]).await?; - let invalid_range: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (chars.clone(), -1, 1)).await; + let invalid_range: Result = jvm + .invoke_virtual(&reader, "java/io/BufferedReader", "read", "([CII)I", (chars.clone(), -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid_range else { panic!("negative offset must throw IndexOutOfBoundsException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let overflowing_range: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (chars.clone(), 3, 2)).await; + let overflowing_range: Result = jvm + .invoke_virtual(&reader, "java/io/BufferedReader", "read", "([CII)I", (chars.clone(), 3, 2)) + .await; let Err(JavaError::JavaException(exception)) = overflowing_range else { panic!("overflowing range must throw IndexOutOfBoundsException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); let null_chars: ClassInstanceRef> = None.into(); - let null_result: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (null_chars, 0, 0)).await; + let null_result: Result = jvm + .invoke_virtual(&reader, "java/io/BufferedReader", "read", "([CII)I", (null_chars, 0, 0)) + .await; let Err(JavaError::JavaException(exception)) = null_result else { panic!("null destination must throw NullPointerException"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'a' as i32); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 1, 2)).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'a' as i32 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "([CII)I", (chars.clone(), 1, 2)) + .await?, + 2 + ); assert_eq!( jvm.load_array::(&chars, 0, 4).await?, ['?' as JavaChar, 'b' as JavaChar, 'c' as JavaChar, '?' as JavaChar] ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, -1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 0, 0)).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 0, 1)).await?, -1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + -1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "([CII)I", (chars.clone(), 0, 0)) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "([CII)I", (chars.clone(), 0, 1)) + .await?, + -1 + ); let empty = jvm.instantiate_array("C", 0).await?; let input = jvm.new_class("ChunkedReader", "([CI)V", (empty, 1)).await?; let default_reader = jvm.new_class("java/io/BufferedReader", "(Ljava/io/Reader;)V", (input.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&default_reader, "read", "()I", ()).await?, -1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&default_reader, &default_reader.class_definition().name(), "read", "()I", ()) + .await?, + -1 + ); for size in [0, -1] { let invalid_size = jvm @@ -274,11 +302,15 @@ async fn test_buffered_reader_read_line_endings_and_long_lines() -> Result<()> { let (jvm, _, reader) = buffered_reader(&input, 1, 3).await?; for expected in ["first", "second", "third", "", long_line] { - let line: ClassInstanceRef = jvm.invoke_virtual(&reader, "readLine", "()Ljava/lang/String;", ()).await?; + let line: ClassInstanceRef = jvm + .invoke_virtual(&reader, "java/io/BufferedReader", "readLine", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &line).await?, expected); } - let line: ClassInstanceRef = jvm.invoke_virtual(&reader, "readLine", "()Ljava/lang/String;", ()).await?; + let line: ClassInstanceRef = jvm + .invoke_virtual(&reader, "java/io/BufferedReader", "readLine", "()Ljava/lang/String;", ()) + .await?; assert!(line.is_null()); Ok(()) @@ -288,27 +320,59 @@ async fn test_buffered_reader_read_line_endings_and_long_lines() -> Result<()> { async fn test_buffered_reader_mixed_reads_skip_and_ready_share_cursor() -> Result<()> { let (jvm, source, reader) = buffered_reader("abc\ndef", 16, 8).await?; - let negative_skip: Result = jvm.invoke_virtual(&reader, "skip", "(J)J", (-1i64,)).await; + let negative_skip: Result = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "skip", "(J)J", (-1i64,)).await; let Err(JavaError::JavaException(exception)) = negative_skip else { panic!("negative skip must throw IllegalArgumentException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalArgumentException")); - assert!(jvm.invoke_virtual::<_, bool>(&reader, "ready", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'a' as i32); - assert!(!jvm.invoke_virtual::<_, bool>(&source, "ready", "()Z", ()).await?); - assert!(jvm.invoke_virtual::<_, bool>(&reader, "ready", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&reader, "java/io/BufferedReader", "ready", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'a' as i32 + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&source, &source.class_definition().name(), "ready", "()Z", ()) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&reader, "java/io/BufferedReader", "ready", "()Z", ()) + .await? + ); let chars = jvm.instantiate_array("C", 2).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 0, 2)).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "([CII)I", (chars.clone(), 0, 2)) + .await?, + 2 + ); assert_eq!(jvm.load_array::(&chars, 0, 2).await?, ['b' as JavaChar, 'c' as JavaChar]); - let line: ClassInstanceRef = jvm.invoke_virtual(&reader, "readLine", "()Ljava/lang/String;", ()).await?; + let line: ClassInstanceRef = jvm + .invoke_virtual(&reader, "java/io/BufferedReader", "readLine", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &line).await?, ""); - assert_eq!(jvm.invoke_virtual::<_, i64>(&reader, "skip", "(J)J", (2i64,)).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'f' as i32); - assert!(!jvm.invoke_virtual::<_, bool>(&reader, "ready", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i64>(&reader, "skip", "(J)J", (2i64,)).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&reader, "java/io/BufferedReader", "skip", "(J)J", (2i64,)) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'f' as i32 + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&reader, "java/io/BufferedReader", "ready", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&reader, "java/io/BufferedReader", "skip", "(J)J", (2i64,)) + .await?, + 0 + ); Ok(()) } @@ -317,41 +381,64 @@ async fn test_buffered_reader_mixed_reads_skip_and_ready_share_cursor() -> Resul async fn test_buffered_reader_mark_reset_preservation_and_invalidation() -> Result<()> { let (jvm, _, reader) = buffered_reader("abcdef", 2, 3).await?; - assert!(jvm.invoke_virtual::<_, bool>(&reader, "markSupported", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'a' as i32); - let _: () = jvm.invoke_virtual(&reader, "mark", "(I)V", (4,)).await?; + assert!( + jvm.invoke_virtual::<_, bool>(&reader, "java/io/BufferedReader", "markSupported", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'a' as i32 + ); + let _: () = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "mark", "(I)V", (4,)).await?; - let negative_mark: Result<()> = jvm.invoke_virtual(&reader, "mark", "(I)V", (-1,)).await; + let negative_mark: Result<()> = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "mark", "(I)V", (-1,)).await; let Err(JavaError::JavaException(exception)) = negative_mark else { panic!("negative read-ahead limit must throw IllegalArgumentException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalArgumentException")); let chars = jvm.instantiate_array("C", 4).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 0, 4)).await?, 4); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "([CII)I", (chars.clone(), 0, 4)) + .await?, + 4 + ); assert_eq!( jvm.load_array::(&chars, 0, 4).await?, ['b' as JavaChar, 'c' as JavaChar, 'd' as JavaChar, 'e' as JavaChar] ); - let _: () = jvm.invoke_virtual(&reader, "reset", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 0, 4)).await?, 4); + let _: () = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "reset", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "([CII)I", (chars.clone(), 0, 4)) + .await?, + 4 + ); assert_eq!( jvm.load_array::(&chars, 0, 4).await?, ['b' as JavaChar, 'c' as JavaChar, 'd' as JavaChar, 'e' as JavaChar] ); let (jvm, _, reader) = buffered_reader("abcd", 2, 2).await?; - let unset_reset: Result<()> = jvm.invoke_virtual(&reader, "reset", "()V", ()).await; + let unset_reset: Result<()> = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "reset", "()V", ()).await; let Err(JavaError::JavaException(exception)) = unset_reset else { panic!("reset without mark must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); - let _: () = jvm.invoke_virtual(&reader, "mark", "(I)V", (2,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'a' as i32); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'b' as i32); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'c' as i32); - let invalidated_reset: Result<()> = jvm.invoke_virtual(&reader, "reset", "()V", ()).await; + let _: () = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "mark", "(I)V", (2,)).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'a' as i32 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'b' as i32 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'c' as i32 + ); + let invalidated_reset: Result<()> = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "reset", "()V", ()).await; let Err(JavaError::JavaException(exception)) = invalidated_reset else { panic!("reset beyond read-ahead limit must throw IOException"); }; @@ -364,12 +451,20 @@ async fn test_buffered_reader_mark_reset_preservation_and_invalidation() -> Resu async fn test_buffered_reader_mark_restores_pending_crlf_state() -> Result<()> { let (jvm, _, reader) = buffered_reader("a\r\nb", 1, 2).await?; - let line: ClassInstanceRef = jvm.invoke_virtual(&reader, "readLine", "()Ljava/lang/String;", ()).await?; + let line: ClassInstanceRef = jvm + .invoke_virtual(&reader, "java/io/BufferedReader", "readLine", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &line).await?, "a"); - let _: () = jvm.invoke_virtual(&reader, "mark", "(I)V", (2,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'b' as i32); - let _: () = jvm.invoke_virtual(&reader, "reset", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'b' as i32); + let _: () = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "mark", "(I)V", (2,)).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'b' as i32 + ); + let _: () = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "reset", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'b' as i32 + ); Ok(()) } @@ -379,12 +474,20 @@ async fn test_buffered_reader_ready_preserves_pending_lf_until_input_is_availabl let (jvm, mut source, reader) = buffered_reader("\r\nX", 3, 2).await?; jvm.put_field(&mut source, "visibleLength", "I", 1).await?; - let line: ClassInstanceRef = jvm.invoke_virtual(&reader, "readLine", "()Ljava/lang/String;", ()).await?; + let line: ClassInstanceRef = jvm + .invoke_virtual(&reader, "java/io/BufferedReader", "readLine", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &line).await?, ""); - assert!(!jvm.invoke_virtual::<_, bool>(&reader, "ready", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&reader, "java/io/BufferedReader", "ready", "()Z", ()) + .await? + ); jvm.put_field(&mut source, "visibleLength", "I", 3).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'X' as i32); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'X' as i32 + ); Ok(()) } @@ -394,8 +497,14 @@ async fn test_buffered_reader_fill_retries_temporary_zero_read() -> Result<()> { let (jvm, mut source, reader) = buffered_reader("a", 1, 1).await?; jvm.put_field(&mut source, "zeroReads", "I", 1).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'a' as i32); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, -1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + 'a' as i32 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()).await?, + -1 + ); Ok(()) } @@ -409,7 +518,7 @@ async fn test_buffered_reader_serializes_on_inherited_reader_lock() -> Result<() let thread = jvm.new_class("java/lang/Thread", "(Ljava/lang/Runnable;)V", (runner.clone(),)).await?; jvm.monitor_enter(&source).await?; - let _: () = jvm.invoke_virtual(&thread, "start", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&thread, &thread.class_definition().name(), "start", "()V", ()).await?; let mut started = false; for _ in 0..100 { @@ -423,7 +532,7 @@ async fn test_buffered_reader_serializes_on_inherited_reader_lock() -> Result<() let completed_while_lock_was_held = jvm.get_field::(&runner, "done", "Z").await?; jvm.monitor_exit(&source).await?; - let _: () = jvm.invoke_virtual(&thread, "join", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&thread, &thread.class_definition().name(), "join", "()V", ()).await?; assert!(started, "worker thread did not start"); assert!(!completed_while_lock_was_held, "read did not synchronize on Reader.lock"); @@ -436,28 +545,48 @@ async fn test_buffered_reader_serializes_on_inherited_reader_lock() -> Result<() async fn test_buffered_reader_close_is_idempotent_and_closes_all_operations() -> Result<()> { let (jvm, source, reader) = buffered_reader("abc", 2, 2).await?; - let _: () = jvm.invoke_virtual(&reader, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&reader, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&reader, "java/io/BufferedReader", "close", "()V", ()).await?; assert_eq!(jvm.get_field::(&source, "closeCount", "I").await?, 1); - assert!(jvm.invoke_virtual::<_, bool>(&reader, "markSupported", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&reader, "java/io/BufferedReader", "markSupported", "()Z", ()) + .await? + ); let chars = jvm.instantiate_array("C", 1).await?; let operations: Vec<(&str, Result<()>)> = vec![ - ("read()", jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await.map(|_| ())), + ( + "read()", + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "()I", ()) + .await + .map(|_| ()), + ), ( "read(char[],off,len)", - jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars, 0, 1)).await.map(|_| ()), + jvm.invoke_virtual::<_, i32>(&reader, "java/io/BufferedReader", "read", "([CII)I", (chars, 0, 1)) + .await + .map(|_| ()), ), ( "readLine", - jvm.invoke_virtual::<_, ClassInstanceRef>(&reader, "readLine", "()Ljava/lang/String;", ()) + jvm.invoke_virtual::<_, ClassInstanceRef>(&reader, "java/io/BufferedReader", "readLine", "()Ljava/lang/String;", ()) + .await + .map(|_| ()), + ), + ( + "skip", + jvm.invoke_virtual::<_, i64>(&reader, "java/io/BufferedReader", "skip", "(J)J", (1i64,)) + .await + .map(|_| ()), + ), + ( + "ready", + jvm.invoke_virtual::<_, bool>(&reader, "java/io/BufferedReader", "ready", "()Z", ()) .await .map(|_| ()), ), - ("skip", jvm.invoke_virtual::<_, i64>(&reader, "skip", "(J)J", (1i64,)).await.map(|_| ())), - ("ready", jvm.invoke_virtual::<_, bool>(&reader, "ready", "()Z", ()).await.map(|_| ())), - ("mark", jvm.invoke_virtual(&reader, "mark", "(I)V", (1,)).await), - ("reset", jvm.invoke_virtual(&reader, "reset", "()V", ()).await), + ("mark", jvm.invoke_virtual(&reader, "java/io/BufferedReader", "mark", "(I)V", (1,)).await), + ("reset", jvm.invoke_virtual(&reader, "java/io/BufferedReader", "reset", "()V", ()).await), ]; for (name, result) in operations { diff --git a/java_runtime/tests/classes/java/io/test_buffered_streams.rs b/java_runtime/tests/classes/java/io/test_buffered_streams.rs index 3beff407..3ce75a54 100644 --- a/java_runtime/tests/classes/java/io/test_buffered_streams.rs +++ b/java_runtime/tests/classes/java/io/test_buffered_streams.rs @@ -33,7 +33,11 @@ async fn bio_01_bio_02_bio_03_buffered_input_stream_contract() -> Result<()> { jvm.store_array(&mut data, 0, [7i8]).await?; let input = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (data,)).await?; let default_stream = jvm.new_class("java/io/BufferedInputStream", "(Ljava/io/InputStream;)V", (input,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&default_stream, "read", "()I", ()).await?, 7); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&default_stream, &default_stream.class_definition().name(), "read", "()I", ()) + .await?, + 7 + ); let mut data = jvm.instantiate_array("B", 6).await?; jvm.store_array(&mut data, 0, [10i8, 20, 30, 40, 50, 60]).await?; @@ -42,24 +46,71 @@ async fn bio_01_bio_02_bio_03_buffered_input_stream_contract() -> Result<()> { .new_class("java/io/BufferedInputStream", "(Ljava/io/InputStream;I)V", (input, 2)) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&stream, "markSupported", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&stream, "available", "()I", ()).await?, 6); - assert_eq!(jvm.invoke_virtual::<_, i32>(&stream, "read", "()I", ()).await?, 10); + assert!( + jvm.invoke_virtual::<_, bool>(&stream, &stream.class_definition().name(), "markSupported", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stream, &stream.class_definition().name(), "available", "()I", ()) + .await?, + 6 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stream, &stream.class_definition().name(), "read", "()I", ()) + .await?, + 10 + ); - let _: () = jvm.invoke_virtual(&stream, "mark", "(I)V", (4,)).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "mark", "(I)V", (4,)) + .await?; let target = jvm.instantiate_array("B", 6).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&stream, "read", "([BII)I", (target.clone(), 1, 3)).await?, 3); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stream, &stream.class_definition().name(), "read", "([BII)I", (target.clone(), 1, 3)) + .await?, + 3 + ); assert_eq!(jvm.load_array::(&target, 0, 6).await?, [0, 20, 30, 40, 0, 0]); - let _: () = jvm.invoke_virtual(&stream, "reset", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&stream, "read", "()I", ()).await?, 20); - assert_eq!(jvm.invoke_virtual::<_, i64>(&stream, "skip", "(J)J", (2i64,)).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&stream, "read", "()I", ()).await?, 50); - assert_eq!(jvm.invoke_virtual::<_, i64>(&stream, "skip", "(J)J", (-1i64,)).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&stream, "read", "()I", ()).await?, 60); - assert_eq!(jvm.invoke_virtual::<_, i32>(&stream, "read", "()I", ()).await?, -1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&stream, "read", "([BII)I", (target.clone(), 0, 0)).await?, 0); - - let invalid: Result = jvm.invoke_virtual(&stream, "read", "([BII)I", (target, -1, 1)).await; + let _: () = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "reset", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stream, &stream.class_definition().name(), "read", "()I", ()) + .await?, + 20 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&stream, &stream.class_definition().name(), "skip", "(J)J", (2i64,)) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stream, &stream.class_definition().name(), "read", "()I", ()) + .await?, + 50 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&stream, &stream.class_definition().name(), "skip", "(J)J", (-1i64,)) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stream, &stream.class_definition().name(), "read", "()I", ()) + .await?, + 60 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stream, &stream.class_definition().name(), "read", "()I", ()) + .await?, + -1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stream, &stream.class_definition().name(), "read", "([BII)I", (target.clone(), 0, 0)) + .await?, + 0 + ); + + let invalid: Result = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([BII)I", (target, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid else { panic!("invalid range must throw IndexOutOfBoundsException"); }; @@ -72,60 +123,80 @@ async fn bio_01_bio_02_bio_03_buffered_input_stream_contract() -> Result<()> { .new_class("java/io/BufferedInputStream", "(Ljava/io/InputStream;I)V", (input, 2)) .await?; let null_bytes: ClassInstanceRef> = None.into(); - let invalid: Result = jvm.invoke_virtual(&stream, "read", "([BII)I", (null_bytes, -1, 1)).await; + let invalid: Result = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([BII)I", (null_bytes, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid else { panic!("open stream must reject a null array with NullPointerException before validating the range"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let _: () = jvm.invoke_virtual(&stream, "mark", "(I)V", (2,)).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "mark", "(I)V", (2,)) + .await?; let bytes = jvm.instantiate_array("B", 3).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&stream, "read", "([BII)I", (bytes, 0, 3)).await?, 3); - let reset: Result<()> = jvm.invoke_virtual(&stream, "reset", "()V", ()).await; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stream, &stream.class_definition().name(), "read", "([BII)I", (bytes, 0, 3)) + .await?, + 3 + ); + let reset: Result<()> = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "reset", "()V", ()).await; let Err(JavaError::JavaException(exception)) = reset else { panic!("reading past mark limit must invalidate the mark"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; - let closed: Result = jvm.invoke_virtual(&stream, "read", "()I", ()).await; + let _: () = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "close", "()V", ()).await?; + let closed: Result = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "read", "()I", ()).await; let Err(JavaError::JavaException(exception)) = closed else { panic!("read after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); - let closed: Result = jvm.invoke_virtual(&stream, "available", "()I", ()).await; + let closed: Result = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "available", "()I", ()) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("available after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let empty = jvm.instantiate_array("B", 0).await?; - let closed: Result = jvm.invoke_virtual(&stream, "read", "([BII)I", (empty, 0, 0)).await; + let closed: Result = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([BII)I", (empty, 0, 0)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("zero-length read after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let null_bytes: ClassInstanceRef> = None.into(); - let closed: Result = jvm.invoke_virtual(&stream, "read", "([BII)I", (null_bytes, -1, 1)).await; + let closed: Result = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([BII)I", (null_bytes, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("closed stream must reject a null array with IOException before validating arguments"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let bytes = jvm.instantiate_array("B", 1).await?; - let closed: Result = jvm.invoke_virtual(&stream, "read", "([BII)I", (bytes, -1, 1)).await; + let closed: Result = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([BII)I", (bytes, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("closed stream must reject an invalid range with IOException before validating arguments"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); - let closed: Result = jvm.invoke_virtual(&stream, "skip", "(J)J", (0i64,)).await; + let closed: Result = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "skip", "(J)J", (0i64,)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("zero skip after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let position: i32 = jvm.get_field(&stream, "pos", "I").await?; - let _: () = jvm.invoke_virtual(&stream, "mark", "(I)V", (17,)).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "mark", "(I)V", (17,)) + .await?; assert_eq!(jvm.get_field::(&stream, "marklimit", "I").await?, 17); assert_eq!(jvm.get_field::(&stream, "markpos", "I").await?, position); - let closed: Result<()> = jvm.invoke_virtual(&stream, "reset", "()V", ()).await; + let closed: Result<()> = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "reset", "()V", ()).await; let Err(JavaError::JavaException(exception)) = closed else { panic!("reset after a post-close mark must still throw IOException"); }; @@ -160,9 +231,15 @@ async fn bio_04_bio_05_buffered_output_stream_contract() -> Result<()> { let default_stream = jvm .new_class("java/io/BufferedOutputStream", "(Ljava/io/OutputStream;)V", (output.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&default_stream, "write", "(I)V", (8,)).await?; - let _: () = jvm.invoke_virtual(&default_stream, "flush", "()V", ()).await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let _: () = jvm + .invoke_virtual(&default_stream, &default_stream.class_definition().name(), "write", "(I)V", (8,)) + .await?; + let _: () = jvm + .invoke_virtual(&default_stream, &default_stream.class_definition().name(), "flush", "()V", ()) + .await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toByteArray", "()[B", ()) + .await?; assert_eq!(jvm.load_array::(&bytes, 0, 1).await?, [8]); let output = jvm.new_class("java/io/ByteArrayOutputStream", "()V", ()).await?; @@ -170,42 +247,65 @@ async fn bio_04_bio_05_buffered_output_stream_contract() -> Result<()> { .new_class("java/io/BufferedOutputStream", "(Ljava/io/OutputStream;I)V", (output.clone(), 3)) .await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (1,)).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "(I)V", (1,)) + .await?; let mut bytes = jvm.instantiate_array("B", 5).await?; jvm.store_array(&mut bytes, 0, [10i8, 20, 30, 40, 50]).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "([BII)V", (bytes.clone(), 1, 2)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&output, "size", "()I", ()).await?, 0); + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "([BII)V", (bytes.clone(), 1, 2)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&output, &output.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); - let _: () = jvm.invoke_virtual(&stream, "write", "([BII)V", (bytes.clone(), 2, 3)).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "([BII)V", (bytes.clone(), 2, 3)) + .await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&output, "size", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&output, &output.class_definition().name(), "size", "()I", ()) + .await?, 6, "a large write must flush buffered bytes before writing through" ); - let invalid: Result<()> = jvm.invoke_virtual(&stream, "write", "([BII)V", (bytes.clone(), -1, 1)).await; + let invalid: Result<()> = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "([BII)V", (bytes.clone(), -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid else { panic!("invalid range must throw IndexOutOfBoundsException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let _: () = jvm.invoke_virtual(&stream, "write", "([BII)V", (bytes, 5, 0)).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "([BII)V", (bytes, 5, 0)) + .await?; - let _: () = jvm.invoke_virtual(&stream, "flush", "()V", ()).await?; - let actual: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let _: () = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "flush", "()V", ()).await?; + let actual: ClassInstanceRef> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toByteArray", "()[B", ()) + .await?; assert_eq!(jvm.load_array::(&actual, 0, 6).await?, [1, 20, 30, 30, 40, 50]); - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (99,)).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; - let actual: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "(I)V", (99,)) + .await?; + let _: () = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "close", "()V", ()).await?; + let actual: ClassInstanceRef> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toByteArray", "()[B", ()) + .await?; assert_eq!(jvm.load_array::(&actual, 0, 7).await?, [1, 20, 30, 30, 40, 50, 99]); - let closed: Result<()> = jvm.invoke_virtual(&stream, "write", "(I)V", (100,)).await; + let closed: Result<()> = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "(I)V", (100,)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("write after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); - let closed: Result<()> = jvm.invoke_virtual(&stream, "flush", "()V", ()).await; + let closed: Result<()> = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "flush", "()V", ()).await; let Err(JavaError::JavaException(exception)) = closed else { panic!("flush after close must throw IOException"); }; @@ -247,10 +347,21 @@ async fn bio_06_bio_07_buffered_writer_contract() -> Result<()> { let default_writer = jvm .new_class("java/io/BufferedWriter", "(Ljava/io/Writer;)V", (default_output.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&default_writer, "write", "(I)V", ('V' as i32,)).await?; - let _: () = jvm.invoke_virtual(&default_writer, "flush", "()V", ()).await?; - let actual: ClassInstanceRef = - jvm.invoke_virtual(&default_output, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&default_writer, &default_writer.class_definition().name(), "write", "(I)V", ('V' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&default_writer, &default_writer.class_definition().name(), "flush", "()V", ()) + .await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual( + &default_output, + &default_output.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, "V"); let output = jvm.new_class("java/io/StringWriter", "()V", ()).await?; @@ -263,7 +374,9 @@ async fn bio_06_bio_07_buffered_writer_contract() -> Result<()> { output.identity(), "BufferedWriter must use its backing writer as Writer.lock" ); - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", ('A' as i32,)).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(I)V", ('A' as i32,)) + .await?; let mut chars = jvm.instantiate_array("C", 5).await?; jvm.store_array( &mut chars, @@ -271,52 +384,81 @@ async fn bio_06_bio_07_buffered_writer_contract() -> Result<()> { ['0' as JavaChar, 'B' as JavaChar, 'C' as JavaChar, 'D' as JavaChar, '4' as JavaChar], ) .await?; - let _: () = jvm.invoke_virtual(&writer, "write", "([CII)V", (chars.clone(), 1, 2)).await?; - let value: ClassInstanceRef = - jvm.invoke_virtual(&output, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "([CII)V", (chars.clone(), 1, 2)) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, ""); let value = JavaLangString::from_rust_string(&jvm, "xyZ!").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;II)V", (value, 1, 3)).await?; - let _: () = jvm.invoke_virtual(&writer, "newLine", "()V", ()).await?; + let _: () = jvm + .invoke_virtual( + &writer, + &writer.class_definition().name(), + "write", + "(Ljava/lang/String;II)V", + (value, 1, 3), + ) + .await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "newLine", "()V", ()) + .await?; - let invalid: Result<()> = jvm.invoke_virtual(&writer, "write", "([CII)V", (chars, -1, 1)).await; + let invalid: Result<()> = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "([CII)V", (chars, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid else { panic!("invalid range must throw IndexOutOfBoundsException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let _: () = jvm.invoke_virtual(&writer, "flush", "()V", ()).await?; - let actual: ClassInstanceRef = - jvm.invoke_virtual(&output, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "flush", "()V", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, "ABCyZ!|"); - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", ('Q' as i32,)).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; - let actual: ClassInstanceRef = - jvm.invoke_virtual(&output, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(I)V", ('Q' as i32,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, "ABCyZ!|Q"); - let closed: Result<()> = jvm.invoke_virtual(&writer, "write", "(I)V", ('R' as i32,)).await; + let closed: Result<()> = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(I)V", ('R' as i32,)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("write after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); - let closed: Result<()> = jvm.invoke_virtual(&writer, "flush", "()V", ()).await; + let closed: Result<()> = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "flush", "()V", ()).await; let Err(JavaError::JavaException(exception)) = closed else { panic!("flush after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let null_chars: ClassInstanceRef> = None.into(); - let closed: Result<()> = jvm.invoke_virtual(&writer, "write", "([CII)V", (null_chars, -1, 1)).await; + let closed: Result<()> = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "([CII)V", (null_chars, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("closed writer must reject a null array with IOException before validating arguments"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let null_string: ClassInstanceRef = None.into(); let closed: Result<()> = jvm - .invoke_virtual(&writer, "write", "(Ljava/lang/String;II)V", (null_string, -1, 1)) + .invoke_virtual( + &writer, + &writer.class_definition().name(), + "write", + "(Ljava/lang/String;II)V", + (null_string, -1, 1), + ) .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("closed writer must reject a null string with IOException before validating arguments"); @@ -327,13 +469,18 @@ async fn bio_06_bio_07_buffered_writer_contract() -> Result<()> { let writer = jvm .new_class("java/io/BufferedWriter", "(Ljava/io/Writer;I)V", (output.clone(), 2)) .await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", ('P' as i32,)).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(I)V", ('P' as i32,)) + .await?; let mut chars = jvm.instantiate_array("C", 3).await?; jvm.store_array(&mut chars, 0, ['A' as JavaChar, 'B' as JavaChar, 'C' as JavaChar]) .await?; - let _: () = jvm.invoke_virtual(&writer, "write", "([CII)V", (chars, 0, 3)).await?; - let actual: ClassInstanceRef = - jvm.invoke_virtual(&output, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "([CII)V", (chars, 0, 3)) + .await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!( JavaLangString::to_rust_string(&jvm, &actual).await?, "PABC", diff --git a/java_runtime/tests/classes/java/io/test_byte_array_input_stream.rs b/java_runtime/tests/classes/java/io/test_byte_array_input_stream.rs index cbb6d07d..2690c192 100644 --- a/java_runtime/tests/classes/java/io/test_byte_array_input_stream.rs +++ b/java_runtime/tests/classes/java/io/test_byte_array_input_stream.rs @@ -22,13 +22,17 @@ async fn null_byte_arrays_throw_null_pointer_exception() -> Result<()> { let data = jvm.instantiate_array("B", 1).await?; let stream = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (data,)).await?; - let result: Result = jvm.invoke_virtual(&stream, "read", "([B)I", (null.clone(),)).await; + let result: Result = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([B)I", (null.clone(),)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("null read buffer must throw NullPointerException"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let result: Result = jvm.invoke_virtual(&stream, "read", "([BII)I", (null, 0, 0)).await; + let result: Result = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([BII)I", (null, 0, 0)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("null ranged read buffer must throw NullPointerException"); }; @@ -46,17 +50,19 @@ async fn test_mark_reset() -> Result<()> { let stream = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (buffer,)).await?; - let first: i32 = jvm.invoke_virtual(&stream, "read", "()I", ()).await?; + let first: i32 = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "read", "()I", ()).await?; assert_eq!(first, 10); - let _: () = jvm.invoke_virtual(&stream, "mark", "(I)V", (100,)).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "mark", "(I)V", (100,)) + .await?; - let second: i32 = jvm.invoke_virtual(&stream, "read", "()I", ()).await?; + let second: i32 = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "read", "()I", ()).await?; assert_eq!(second, 20); - let _: () = jvm.invoke_virtual(&stream, "reset", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "reset", "()V", ()).await?; - let again: i32 = jvm.invoke_virtual(&stream, "read", "()I", ()).await?; + let again: i32 = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "read", "()I", ()).await?; assert_eq!(again, 20); Ok(()) diff --git a/java_runtime/tests/classes/java/io/test_byte_array_output_stream.rs b/java_runtime/tests/classes/java/io/test_byte_array_output_stream.rs index 33b97444..66f86e0d 100644 --- a/java_runtime/tests/classes/java/io/test_byte_array_output_stream.rs +++ b/java_runtime/tests/classes/java/io/test_byte_array_output_stream.rs @@ -43,13 +43,25 @@ async fn test_byte_array_output_stream() -> Result<()> { let jvm = test_jvm().await?; let stream = jvm.new_class("java/io/ByteArrayOutputStream", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (b'H' as i32,)).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (b'e' as i32,)).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (b'l' as i32,)).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (b'l' as i32,)).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (b'o' as i32,)).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "(I)V", (b'H' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "(I)V", (b'e' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "(I)V", (b'l' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "(I)V", (b'l' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "(I)V", (b'o' as i32,)) + .await?; - let buf = jvm.invoke_virtual(&stream, "toByteArray", "()[B", ()).await?; + let buf = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "toByteArray", "()[B", ()) + .await?; let mut bytes = vec![0; 5]; jvm.array_raw_buffer(&buf).await?.read(0, &mut bytes)?; @@ -65,13 +77,17 @@ async fn null_byte_arrays_throw_null_pointer_exception() -> Result<()> { let stream = jvm.new_class("java/io/ByteArrayOutputStream", "()V", ()).await?; let null: ClassInstanceRef> = None.into(); - let result: Result<()> = jvm.invoke_virtual(&stream, "write", "([B)V", (null.clone(),)).await; + let result: Result<()> = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "([B)V", (null.clone(),)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("null write buffer must throw NullPointerException"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let result: Result<()> = jvm.invoke_virtual(&stream, "write", "([BII)V", (null, 0, 0)).await; + let result: Result<()> = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "([BII)V", (null, 0, 0)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("null ranged write buffer must throw NullPointerException"); }; @@ -87,26 +103,46 @@ async fn baos_01_write_to_and_named_encoding_use_only_logical_count_after_close( let stream = jvm.new_class("java/io/ByteArrayOutputStream", "(I)V", (16,)).await?; let mut bytes = jvm.instantiate_array("B", 2).await?; jvm.store_array(&mut bytes, 0, [b'O' as i8, b'K' as i8]).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "([BII)V", (bytes, 0, 2)).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "([BII)V", (bytes, 0, 2)) + .await?; + let _: () = jvm.invoke_virtual(&stream, &stream.class_definition().name(), "close", "()V", ()).await?; let destination = jvm.new_class("java/io/ByteArrayOutputStream", "()V", ()).await?; let destination_output: ClassInstanceRef = destination.clone().into(); let _: () = jvm - .invoke_virtual(&stream, "writeTo", "(Ljava/io/OutputStream;)V", (destination_output,)) + .invoke_virtual( + &stream, + &stream.class_definition().name(), + "writeTo", + "(Ljava/io/OutputStream;)V", + (destination_output,), + ) + .await?; + let copied: ClassInstanceRef> = jvm + .invoke_virtual(&destination, &destination.class_definition().name(), "toByteArray", "()[B", ()) .await?; - let copied: ClassInstanceRef> = jvm.invoke_virtual(&destination, "toByteArray", "()[B", ()).await?; assert_eq!(jvm.array_length(&copied).await?, 2); assert_eq!(jvm.load_array::(&copied, 0, 2).await?, [b'O' as i8, b'K' as i8]); let encoding = JavaLangString::from_rust_string(&jvm, "UTF-8").await?; let text = jvm - .invoke_virtual(&stream, "toString", "(Ljava/lang/String;)Ljava/lang/String;", (encoding,)) + .invoke_virtual( + &stream, + &stream.class_definition().name(), + "toString", + "(Ljava/lang/String;)Ljava/lang/String;", + (encoding,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "OK"); - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (b'!' as i32,)).await?; - let text = jvm.invoke_virtual(&stream, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "write", "(I)V", (b'!' as i32,)) + .await?; + let text = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "OK!"); Ok(()) @@ -118,7 +154,15 @@ async fn baos_01_rejects_null_and_unknown_encoding() -> Result<()> { let stream = jvm.new_class("java/io/ByteArrayOutputStream", "()V", ()).await?; let null_output: ClassInstanceRef = None.into(); - let result: Result<()> = jvm.invoke_virtual(&stream, "writeTo", "(Ljava/io/OutputStream;)V", (null_output,)).await; + let result: Result<()> = jvm + .invoke_virtual( + &stream, + &stream.class_definition().name(), + "writeTo", + "(Ljava/io/OutputStream;)V", + (null_output,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("null output must throw NullPointerException"); }; @@ -128,6 +172,7 @@ async fn baos_01_rejects_null_and_unknown_encoding() -> Result<()> { let result = jvm .invoke_virtual::<_, ClassInstanceRef>( &stream, + &stream.class_definition().name(), "toString", "(Ljava/lang/String;)Ljava/lang/String;", (null_encoding,), @@ -142,6 +187,7 @@ async fn baos_01_rejects_null_and_unknown_encoding() -> Result<()> { let result = jvm .invoke_virtual::<_, ClassInstanceRef>( &stream, + &stream.class_definition().name(), "toString", "(Ljava/lang/String;)Ljava/lang/String;", (unknown,), diff --git a/java_runtime/tests/classes/java/io/test_char_streams.rs b/java_runtime/tests/classes/java/io/test_char_streams.rs index 0d676ddd..f57e0373 100644 --- a/java_runtime/tests/classes/java/io/test_char_streams.rs +++ b/java_runtime/tests/classes/java/io/test_char_streams.rs @@ -16,55 +16,99 @@ async fn cr_01_cr_02_string_reader_contract() -> Result<()> { let value = JavaLangString::from_rust_string(&jvm, "A한BC").await?; let reader = jvm.new_class("java/io/StringReader", "(Ljava/lang/String;)V", (value,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&reader, "ready", "()Z", ()).await?); - assert!(jvm.invoke_virtual::<_, bool>(&reader, "markSupported", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'A' as i32); + assert!( + jvm.invoke_virtual::<_, bool>(&reader, &reader.class_definition().name(), "ready", "()Z", ()) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&reader, &reader.class_definition().name(), "markSupported", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + 'A' as i32 + ); - let _: () = jvm.invoke_virtual(&reader, "mark", "(I)V", (10,)).await?; + let _: () = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "mark", "(I)V", (10,)) + .await?; let chars = jvm.instantiate_array("C", 5).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 1, 2)).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([CII)I", (chars.clone(), 1, 2)) + .await?, + 2 + ); assert_eq!( jvm.load_array::(&chars, 0, 5).await?, [0, '한' as JavaChar, 'B' as JavaChar, 0, 0] ); - let _: () = jvm.invoke_virtual(&reader, "reset", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, '한' as i32); - assert_eq!(jvm.invoke_virtual::<_, i64>(&reader, "skip", "(J)J", (-2i64,)).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i64>(&reader, "skip", "(J)J", (10i64,)).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, -1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 0, 0)).await?, 0); + let _: () = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "reset", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + '한' as i32 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&reader, &reader.class_definition().name(), "skip", "(J)J", (-2i64,)) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&reader, &reader.class_definition().name(), "skip", "(J)J", (10i64,)) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + -1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([CII)I", (chars.clone(), 0, 0)) + .await?, + 0 + ); - let invalid: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (chars, -1, 1)).await; + let invalid: Result = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "read", "([CII)I", (chars, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid else { panic!("invalid range must throw IndexOutOfBoundsException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let invalid_mark: Result<()> = jvm.invoke_virtual(&reader, "mark", "(I)V", (-1,)).await; + let invalid_mark: Result<()> = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "mark", "(I)V", (-1,)) + .await; let Err(JavaError::JavaException(exception)) = invalid_mark else { panic!("negative read-ahead limit must throw IllegalArgumentException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalArgumentException")); - let _: () = jvm.invoke_virtual(&reader, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&reader, "close", "()V", ()).await?; - let closed: Result = jvm.invoke_virtual(&reader, "ready", "()Z", ()).await; + let _: () = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "close", "()V", ()).await?; + let closed: Result = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "ready", "()Z", ()).await; let Err(JavaError::JavaException(exception)) = closed else { panic!("ready after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); - let closed: Result = jvm.invoke_virtual(&reader, "read", "()I", ()).await; + let closed: Result = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "read", "()I", ()).await; let Err(JavaError::JavaException(exception)) = closed else { panic!("read after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let null_chars: ClassInstanceRef> = None.into(); - let closed: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (null_chars, -1, 1)).await; + let closed: Result = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "read", "([CII)I", (null_chars, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("closed StringReader must throw IOException before validating a null target"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let target = jvm.instantiate_array("C", 1).await?; - let closed: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (target, 2, 1)).await; + let closed: Result = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "read", "([CII)I", (target, 2, 1)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("closed StringReader must throw IOException before validating the target range"); }; @@ -94,7 +138,11 @@ async fn cr_03_cr_04_char_array_reader_contract() -> Result<()> { let mut chars = jvm.instantiate_array("C", 1).await?; jvm.store_array(&mut chars, 0, ['X' as JavaChar]).await?; let default_reader = jvm.new_class("java/io/CharArrayReader", "([C)V", (chars,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&default_reader, "read", "()I", ()).await?, 'X' as i32); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&default_reader, &default_reader.class_definition().name(), "read", "()I", ()) + .await?, + 'X' as i32 + ); let mut chars = jvm.instantiate_array("C", 5).await?; jvm.store_array( @@ -104,44 +152,93 @@ async fn cr_03_cr_04_char_array_reader_contract() -> Result<()> { ) .await?; let reader = jvm.new_class("java/io/CharArrayReader", "([CII)V", (chars, 1, 3)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&reader, "ready", "()Z", ()).await?); - assert!(jvm.invoke_virtual::<_, bool>(&reader, "markSupported", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'A' as i32); - let _: () = jvm.invoke_virtual(&reader, "reset", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'A' as i32); - let _: () = jvm.invoke_virtual(&reader, "mark", "(I)V", (2,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&reader, "skip", "(J)J", (1i64,)).await?, 1); - let _: () = jvm.invoke_virtual(&reader, "reset", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'B' as i32); + assert!( + jvm.invoke_virtual::<_, bool>(&reader, &reader.class_definition().name(), "ready", "()Z", ()) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&reader, &reader.class_definition().name(), "markSupported", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + 'A' as i32 + ); + let _: () = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "reset", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + 'A' as i32 + ); + let _: () = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "mark", "(I)V", (2,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i64>(&reader, &reader.class_definition().name(), "skip", "(J)J", (1i64,)) + .await?, + 1 + ); + let _: () = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "reset", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + 'B' as i32 + ); let target = jvm.instantiate_array("C", 2).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (target.clone(), 0, 1)).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([CII)I", (target.clone(), 0, 1)) + .await?, + 1 + ); assert_eq!(jvm.load_array::(&target, 0, 2).await?, ['C' as JavaChar, 0]); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, -1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (target.clone(), 0, 0)).await?, 0); - assert!(!jvm.invoke_virtual::<_, bool>(&reader, "ready", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i64>(&reader, "skip", "(J)J", (-1i64,)).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + -1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([CII)I", (target.clone(), 0, 0)) + .await?, + 0 + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&reader, &reader.class_definition().name(), "ready", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&reader, &reader.class_definition().name(), "skip", "(J)J", (-1i64,)) + .await?, + 0 + ); - let invalid: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (target, 2, 1)).await; + let invalid: Result = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "read", "([CII)I", (target, 2, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid else { panic!("invalid target range must throw IndexOutOfBoundsException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let _: () = jvm.invoke_virtual(&reader, "close", "()V", ()).await?; - let closed: Result = jvm.invoke_virtual(&reader, "read", "()I", ()).await; + let _: () = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "close", "()V", ()).await?; + let closed: Result = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "read", "()I", ()).await; let Err(JavaError::JavaException(exception)) = closed else { panic!("read after close must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let null_chars: ClassInstanceRef> = None.into(); - let closed: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (null_chars, -1, 1)).await; + let closed: Result = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "read", "([CII)I", (null_chars, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("closed CharArrayReader must throw IOException before validating a null target"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); let target = jvm.instantiate_array("C", 1).await?; - let closed: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (target, 2, 1)).await; + let closed: Result = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "read", "([CII)I", (target, 2, 1)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("closed CharArrayReader must throw IOException before validating the target range"); }; @@ -161,22 +258,42 @@ async fn cw_01_cw_02_char_array_writer_contract() -> Result<()> { assert!(jvm.is_instance(&*exception, "java/lang/IllegalArgumentException")); let writer = jvm.new_class("java/io/CharArrayWriter", "(I)V", (1,)).await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", ('A' as i32,)).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(I)V", ('A' as i32,)) + .await?; let mut chars = jvm.instantiate_array("C", 4).await?; jvm.store_array(&mut chars, 0, ['0' as JavaChar, 'B' as JavaChar, 'C' as JavaChar, '3' as JavaChar]) .await?; - let _: () = jvm.invoke_virtual(&writer, "write", "([CII)V", (chars.clone(), 1, 2)).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "([CII)V", (chars.clone(), 1, 2)) + .await?; let value = JavaLangString::from_rust_string(&jvm, "xDEy").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;II)V", (value, 1, 2)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&writer, "size", "()I", ()).await?, 5); + let _: () = jvm + .invoke_virtual( + &writer, + &writer.class_definition().name(), + "write", + "(Ljava/lang/String;II)V", + (value, 1, 2), + ) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&writer, &writer.class_definition().name(), "size", "()I", ()) + .await?, + 5 + ); - let invalid: Result<()> = jvm.invoke_virtual(&writer, "write", "([CII)V", (chars, -1, 1)).await; + let invalid: Result<()> = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "([CII)V", (chars, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid else { panic!("invalid range must throw IndexOutOfBoundsException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let copy: ClassInstanceRef> = jvm.invoke_virtual(&writer, "toCharArray", "()[C", ()).await?; + let copy: ClassInstanceRef> = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "toCharArray", "()[C", ()) + .await?; assert_eq!( jvm.load_array::(©, 0, 5).await?, ['A' as JavaChar, 'B' as JavaChar, 'C' as JavaChar, 'D' as JavaChar, 'E' as JavaChar] @@ -184,22 +301,48 @@ async fn cw_01_cw_02_char_array_writer_contract() -> Result<()> { let mut copy = copy; jvm.store_array(&mut copy, 0, ['Z' as JavaChar]).await?; - let string: ClassInstanceRef = jvm.invoke_virtual(&writer, "toString", "()Ljava/lang/String;", ()).await?; + let string: ClassInstanceRef = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &string).await?, "ABCDE"); let output = jvm.new_class("java/io/StringWriter", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&writer, "writeTo", "(Ljava/io/Writer;)V", (output.clone(),)).await?; - let string: ClassInstanceRef = jvm.invoke_virtual(&output, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual( + &writer, + &writer.class_definition().name(), + "writeTo", + "(Ljava/io/Writer;)V", + (output.clone(),), + ) + .await?; + let string: ClassInstanceRef = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &string).await?, "ABCDE"); - let _: () = jvm.invoke_virtual(&writer, "flush", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", ('F' as i32,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&writer, "size", "()I", ()).await?, 6); - let _: () = jvm.invoke_virtual(&writer, "reset", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&writer, "size", "()I", ()).await?, 0); + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "flush", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(I)V", ('F' as i32,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&writer, &writer.class_definition().name(), "size", "()I", ()) + .await?, + 6 + ); + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "reset", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&writer, &writer.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); let default_writer = jvm.new_class("java/io/CharArrayWriter", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&default_writer, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&default_writer, &default_writer.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/io/test_data_input_stream.rs b/java_runtime/tests/classes/java/io/test_data_input_stream.rs index 6b7bbcee..3135dda0 100644 --- a/java_runtime/tests/classes/java/io/test_data_input_stream.rs +++ b/java_runtime/tests/classes/java/io/test_data_input_stream.rs @@ -25,28 +25,50 @@ async fn test_data_input_stream() -> Result<()> { .new_class("java/io/DataInputStream", "(Ljava/io/InputStream;)V", (input_stream,)) .await?; - let available: i32 = jvm.invoke_virtual(&data_input_stream, "available", "()I", ()).await?; + let available: i32 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "available", "()I", ()) + .await?; assert_eq!(available, data_len as i32); - let byte: i8 = jvm.invoke_virtual(&data_input_stream, "readByte", "()B", ()).await?; + let byte: i8 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readByte", "()B", ()) + .await?; assert_eq!(byte, 0x01); - let short: i16 = jvm.invoke_virtual(&data_input_stream, "readShort", "()S", ()).await?; + let short: i16 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readShort", "()S", ()) + .await?; assert_eq!(short, 0x0203); - let int: i32 = jvm.invoke_virtual(&data_input_stream, "readInt", "()I", ()).await?; + let int: i32 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readInt", "()I", ()) + .await?; assert_eq!(int, 0x04050607); - let long: i64 = jvm.invoke_virtual(&data_input_stream, "readLong", "()J", ()).await?; + let long: i64 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readLong", "()J", ()) + .await?; assert_eq!(long, 0x08090a0b0c0d0e0f); - let float: f32 = jvm.invoke_virtual(&data_input_stream, "readFloat", "()F", ()).await?; + let float: f32 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readFloat", "()F", ()) + .await?; assert_eq!(float, f32::from_be_bytes([0x10, 0x11, 0x12, 0x13])); - let double: f64 = jvm.invoke_virtual(&data_input_stream, "readDouble", "()D", ()).await?; + let double: f64 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readDouble", "()D", ()) + .await?; assert_eq!(double, f64::from_be_bytes([0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b])); - let utf: ClassInstanceRef = jvm.invoke_virtual(&data_input_stream, "readUTF", "()Ljava/lang/String;", ()).await?; + let utf: ClassInstanceRef = jvm + .invoke_virtual( + &data_input_stream, + &data_input_stream.class_definition().name(), + "readUTF", + "()Ljava/lang/String;", + (), + ) + .await?; let string = JavaLangString::to_rust_string(&jvm, &utf).await?; assert_eq!(string, "abcbd"); @@ -71,40 +93,74 @@ async fn test_data_input_stream_high_bit() -> Result<()> { .new_class("java/io/DataInputStream", "(Ljava/io/InputStream;)V", (input_stream,)) .await?; - let available: i32 = jvm.invoke_virtual(&data_input_stream, "available", "()I", ()).await?; + let available: i32 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "available", "()I", ()) + .await?; assert_eq!(available, data_len as i32); - let byte: i8 = jvm.invoke_virtual(&data_input_stream, "readByte", "()B", ()).await?; + let byte: i8 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readByte", "()B", ()) + .await?; assert_eq!(byte, i8::from_be_bytes([0x81])); - let short: i16 = jvm.invoke_virtual(&data_input_stream, "readShort", "()S", ()).await?; + let short: i16 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readShort", "()S", ()) + .await?; assert_eq!(short, i16::from_be_bytes([0x82, 0x83])); - let int: i32 = jvm.invoke_virtual(&data_input_stream, "readInt", "()I", ()).await?; + let int: i32 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readInt", "()I", ()) + .await?; assert_eq!(int, i32::from_be_bytes([0x84, 0x85, 0x86, 0x87])); - let long: i64 = jvm.invoke_virtual(&data_input_stream, "readLong", "()J", ()).await?; + let long: i64 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readLong", "()J", ()) + .await?; assert_eq!(long, i64::from_be_bytes([0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f])); - let float: f32 = jvm.invoke_virtual(&data_input_stream, "readFloat", "()F", ()).await?; + let float: f32 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readFloat", "()F", ()) + .await?; assert_eq!(float, f32::from_be_bytes([0x90, 0x91, 0x92, 0x93])); - let double: f64 = jvm.invoke_virtual(&data_input_stream, "readDouble", "()D", ()).await?; + let double: f64 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readDouble", "()D", ()) + .await?; assert_eq!(double, f64::from_be_bytes([0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b])); let array = jvm.instantiate_array("B", 6).await?; - let _: () = jvm.invoke_virtual(&data_input_stream, "readFully", "([B)V", (array.clone(),)).await?; + let _: () = jvm + .invoke_virtual( + &data_input_stream, + &data_input_stream.class_definition().name(), + "readFully", + "([B)V", + (array.clone(),), + ) + .await?; let mut buffer = vec![0; 6]; jvm.array_raw_buffer(&array).await?.read(0, &mut buffer)?; assert_eq!(buffer, vec![0x10, 0x11, 0x12, 0x13, 0x14, 0x15]); - let skipped: i32 = jvm.invoke_virtual(&data_input_stream, "skipBytes", "(I)I", (2,)).await?; + let skipped: i32 = jvm + .invoke_virtual( + &data_input_stream, + &data_input_stream.class_definition().name(), + "skipBytes", + "(I)I", + (2,), + ) + .await?; assert_eq!(skipped, 2); - let short: i16 = jvm.invoke_virtual(&data_input_stream, "readShort", "()S", ()).await?; + let short: i16 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "readShort", "()S", ()) + .await?; assert_eq!(short, i16::from_be_bytes([0x18, 0x19])); - let available: i32 = jvm.invoke_virtual(&data_input_stream, "available", "()I", ()).await?; + let available: i32 = jvm + .invoke_virtual(&data_input_stream, &data_input_stream.class_definition().name(), "available", "()I", ()) + .await?; assert_eq!(available, 1); Ok(()) @@ -121,10 +177,10 @@ async fn test_skip_past_eof() -> Result<()> { let bais = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (buffer,)).await?; let dis = jvm.new_class("java/io/DataInputStream", "(Ljava/io/InputStream;)V", (bais,)).await?; - let skipped: i64 = jvm.invoke_virtual(&dis, "skip", "(J)J", (10i64,)).await?; + let skipped: i64 = jvm.invoke_virtual(&dis, &dis.class_definition().name(), "skip", "(J)J", (10i64,)).await?; assert_eq!(skipped, 5); - let read: i32 = jvm.invoke_virtual(&dis, "read", "()I", ()).await?; + let read: i32 = jvm.invoke_virtual(&dis, &dis.class_definition().name(), "read", "()I", ()).await?; assert_eq!(read, -1); Ok(()) diff --git a/java_runtime/tests/classes/java/io/test_data_output_stream.rs b/java_runtime/tests/classes/java/io/test_data_output_stream.rs index cf7f60e3..08e63567 100644 --- a/java_runtime/tests/classes/java/io/test_data_output_stream.rs +++ b/java_runtime/tests/classes/java/io/test_data_output_stream.rs @@ -13,15 +13,41 @@ async fn test_data_output_stream() -> Result<()> { .new_class("java/io/DataOutputStream", "(Ljava/io/OutputStream;)V", (stream.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&data_output_stream, "write", "(I)V", (1,)).await?; + let _: () = jvm + .invoke_virtual(&data_output_stream, &data_output_stream.class_definition().name(), "write", "(I)V", (1,)) + .await?; let string = JavaLangString::from_rust_string(&jvm, "hello, world").await?; let _: () = jvm - .invoke_virtual(&data_output_stream, "writeChars", "(Ljava/lang/String;)V", (string,)) + .invoke_virtual( + &data_output_stream, + &data_output_stream.class_definition().name(), + "writeChars", + "(Ljava/lang/String;)V", + (string,), + ) + .await?; + let _: () = jvm + .invoke_virtual( + &data_output_stream, + &data_output_stream.class_definition().name(), + "writeInt", + "(I)V", + (12341234,), + ) + .await?; + let _: () = jvm + .invoke_virtual( + &data_output_stream, + &data_output_stream.class_definition().name(), + "writeLong", + "(J)V", + (123412341324i64,), + ) .await?; - let _: () = jvm.invoke_virtual(&data_output_stream, "writeInt", "(I)V", (12341234,)).await?; - let _: () = jvm.invoke_virtual(&data_output_stream, "writeLong", "(J)V", (123412341324i64,)).await?; - let bytes = jvm.invoke_virtual(&stream, "toByteArray", "()[B", ()).await?; + let bytes = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "toByteArray", "()[B", ()) + .await?; let length = jvm.array_length(&bytes).await?; let mut buf = vec![0; length]; @@ -49,10 +75,18 @@ async fn test_data_output_stream_utf() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "hello, world").await?; let _: () = jvm - .invoke_virtual(&data_output_stream, "writeUTF", "(Ljava/lang/String;)V", (string,)) + .invoke_virtual( + &data_output_stream, + &data_output_stream.class_definition().name(), + "writeUTF", + "(Ljava/lang/String;)V", + (string,), + ) .await?; - let bytes = jvm.invoke_virtual(&stream, "toByteArray", "()[B", ()).await?; + let bytes = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "toByteArray", "()[B", ()) + .await?; let length = jvm.array_length(&bytes).await?; let mut buf = vec![0; length]; @@ -72,39 +106,102 @@ async fn test_data_stream_cldc_primitive_round_trip() -> Result<()> { .new_class("java/io/DataOutputStream", "(Ljava/io/OutputStream;)V", (output.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&data_output, "writeBoolean", "(Z)V", (true,)).await?; - let _: () = jvm.invoke_virtual(&data_output, "writeByte", "(I)V", (0xfe,)).await?; - let _: () = jvm.invoke_virtual(&data_output, "writeShort", "(I)V", (0x1234,)).await?; - let _: () = jvm.invoke_virtual(&data_output, "writeChar", "(I)V", ('한' as i32,)).await?; - let _: () = jvm.invoke_virtual(&data_output, "writeInt", "(I)V", (0x12345678,)).await?; - let _: () = jvm.invoke_virtual(&data_output, "writeLong", "(J)V", (0x0123456789abcdefi64,)).await?; - let _: () = jvm.invoke_virtual(&data_output, "writeFloat", "(F)V", (1.5f32,)).await?; - let _: () = jvm.invoke_virtual(&data_output, "writeDouble", "(D)V", (-2.25f64,)).await?; + let _: () = jvm + .invoke_virtual(&data_output, &data_output.class_definition().name(), "writeBoolean", "(Z)V", (true,)) + .await?; + let _: () = jvm + .invoke_virtual(&data_output, &data_output.class_definition().name(), "writeByte", "(I)V", (0xfe,)) + .await?; + let _: () = jvm + .invoke_virtual(&data_output, &data_output.class_definition().name(), "writeShort", "(I)V", (0x1234,)) + .await?; + let _: () = jvm + .invoke_virtual(&data_output, &data_output.class_definition().name(), "writeChar", "(I)V", ('한' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&data_output, &data_output.class_definition().name(), "writeInt", "(I)V", (0x12345678,)) + .await?; + let _: () = jvm + .invoke_virtual( + &data_output, + &data_output.class_definition().name(), + "writeLong", + "(J)V", + (0x0123456789abcdefi64,), + ) + .await?; + let _: () = jvm + .invoke_virtual(&data_output, &data_output.class_definition().name(), "writeFloat", "(F)V", (1.5f32,)) + .await?; + let _: () = jvm + .invoke_virtual(&data_output, &data_output.class_definition().name(), "writeDouble", "(D)V", (-2.25f64,)) + .await?; let low_bytes = JavaLangString::from_rust_string(&jvm, "Aé").await?; let _: () = jvm - .invoke_virtual(&data_output, "writeBytes", "(Ljava/lang/String;)V", (low_bytes,)) + .invoke_virtual( + &data_output, + &data_output.class_definition().name(), + "writeBytes", + "(Ljava/lang/String;)V", + (low_bytes,), + ) .await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toByteArray", "()[B", ()) + .await?; let input = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (bytes,)).await?; let data_input = jvm.new_class("java/io/DataInputStream", "(Ljava/io/InputStream;)V", (input,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&data_input, "readBoolean", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&data_input, "readUnsignedByte", "()I", ()).await?, 0xfe); - assert_eq!(jvm.invoke_virtual::<_, i16>(&data_input, "readShort", "()S", ()).await?, 0x1234); - assert_eq!(jvm.invoke_virtual::<_, u16>(&data_input, "readChar", "()C", ()).await?, '한' as u16); - assert_eq!(jvm.invoke_virtual::<_, i32>(&data_input, "readInt", "()I", ()).await?, 0x12345678); + assert!( + jvm.invoke_virtual::<_, bool>(&data_input, &data_input.class_definition().name(), "readBoolean", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&data_input, &data_input.class_definition().name(), "readUnsignedByte", "()I", ()) + .await?, + 0xfe + ); + assert_eq!( + jvm.invoke_virtual::<_, i16>(&data_input, &data_input.class_definition().name(), "readShort", "()S", ()) + .await?, + 0x1234 + ); + assert_eq!( + jvm.invoke_virtual::<_, u16>(&data_input, &data_input.class_definition().name(), "readChar", "()C", ()) + .await?, + '한' as u16 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&data_input, &data_input.class_definition().name(), "readInt", "()I", ()) + .await?, + 0x12345678 + ); assert_eq!( - jvm.invoke_virtual::<_, i64>(&data_input, "readLong", "()J", ()).await?, + jvm.invoke_virtual::<_, i64>(&data_input, &data_input.class_definition().name(), "readLong", "()J", ()) + .await?, 0x0123456789abcdefi64 ); - assert_eq!(jvm.invoke_virtual::<_, f32>(&data_input, "readFloat", "()F", ()).await?, 1.5); - assert_eq!(jvm.invoke_virtual::<_, f64>(&data_input, "readDouble", "()D", ()).await?, -2.25); assert_eq!( - jvm.invoke_virtual::<_, i32>(&data_input, "readUnsignedByte", "()I", ()).await?, + jvm.invoke_virtual::<_, f32>(&data_input, &data_input.class_definition().name(), "readFloat", "()F", ()) + .await?, + 1.5 + ); + assert_eq!( + jvm.invoke_virtual::<_, f64>(&data_input, &data_input.class_definition().name(), "readDouble", "()D", ()) + .await?, + -2.25 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&data_input, &data_input.class_definition().name(), "readUnsignedByte", "()I", ()) + .await?, b'A' as i32 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&data_input, "readUnsignedByte", "()I", ()).await?, 0xe9); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&data_input, &data_input.class_definition().name(), "readUnsignedByte", "()I", ()) + .await?, + 0xe9 + ); Ok(()) } @@ -118,24 +215,36 @@ async fn test_data_stream_modified_utf_round_trip_and_malformed_input() -> Resul .new_class("java/io/DataOutputStream", "(Ljava/io/OutputStream;)V", (output.clone(),)) .await?; let expected = JavaLangString::from_rust_string(&jvm, "\0A😀한").await?; - let _: () = jvm.invoke_virtual(&data_output, "writeUTF", "(Ljava/lang/String;)V", (expected,)).await?; + let _: () = jvm + .invoke_virtual( + &data_output, + &data_output.class_definition().name(), + "writeUTF", + "(Ljava/lang/String;)V", + (expected,), + ) + .await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toByteArray", "()[B", ()) + .await?; let encoded: Vec = jvm.load_array(&bytes, 0, jvm.array_length(&bytes).await?).await?; assert_eq!(&encoded[2..4], &[-64, -128]); let input = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (bytes,)).await?; let data_input = jvm.new_class("java/io/DataInputStream", "(Ljava/io/InputStream;)V", (input,)).await?; - let decoded: ClassInstanceRef = - jvm.invoke_virtual(&data_input, "readUTF", "()Ljava/lang/String;", ()).await?; + let decoded: ClassInstanceRef = jvm + .invoke_virtual(&data_input, &data_input.class_definition().name(), "readUTF", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &decoded).await?, "\0A😀한"); let mut malformed = jvm.instantiate_array("B", 4).await?; jvm.store_array(&mut malformed, 0, [0i8, 2, -62, 32]).await?; let input = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (malformed,)).await?; let data_input = jvm.new_class("java/io/DataInputStream", "(Ljava/io/InputStream;)V", (input,)).await?; - let result: Result> = - jvm.invoke_virtual(&data_input, "readUTF", "()Ljava/lang/String;", ()).await; + let result: Result> = jvm + .invoke_virtual(&data_input, &data_input.class_definition().name(), "readUTF", "()Ljava/lang/String;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("malformed modified UTF-8 must throw UTFDataFormatException"); }; diff --git a/java_runtime/tests/classes/java/io/test_file_input_stream.rs b/java_runtime/tests/classes/java/io/test_file_input_stream.rs index 7884a5d4..1f93fdd1 100644 --- a/java_runtime/tests/classes/java/io/test_file_input_stream.rs +++ b/java_runtime/tests/classes/java/io/test_file_input_stream.rs @@ -15,7 +15,9 @@ async fn test_file_input_stream_read_buf() -> Result<()> { let fis = jvm.new_class("java/io/FileInputStream", "(Ljava/io/File;)V", (java_file,)).await?; let bytes = jvm.instantiate_array("B", 11).await?; - let read: i32 = jvm.invoke_virtual(&fis, "read", "([B)I", (bytes.clone(),)).await?; + let read: i32 = jvm + .invoke_virtual(&fis, &fis.class_definition().name(), "read", "([B)I", (bytes.clone(),)) + .await?; let length = jvm.array_length(&bytes).await?; let mut buf = vec![0; length]; @@ -37,7 +39,7 @@ async fn test_file_input_stream_read_int() -> Result<()> { let java_file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (file,)).await?; let fis = jvm.new_class("java/io/FileInputStream", "(Ljava/io/File;)V", (java_file,)).await?; - let read: i32 = jvm.invoke_virtual(&fis, "read", "()I", ()).await?; + let read: i32 = jvm.invoke_virtual(&fis, &fis.class_definition().name(), "read", "()I", ()).await?; assert_eq!(read, 104); @@ -54,7 +56,7 @@ async fn test_file_input_stream_available() -> Result<()> { let java_file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (file,)).await?; let fis = jvm.new_class("java/io/FileInputStream", "(Ljava/io/File;)V", (java_file,)).await?; - let available: i32 = jvm.invoke_virtual(&fis, "available", "()I", ()).await?; + let available: i32 = jvm.invoke_virtual(&fis, &fis.class_definition().name(), "available", "()I", ()).await?; assert!(available > 0); @@ -73,7 +75,10 @@ async fn test_file_input_stream_sequential_read() -> Result<()> { let mut reads = vec![]; for _ in 0..6 { - reads.push(jvm.invoke_virtual::<_, i32>(&fis, "read", "()I", ()).await?); + reads.push( + jvm.invoke_virtual::<_, i32>(&fis, &fis.class_definition().name(), "read", "()I", ()) + .await?, + ); } assert_eq!(reads, vec![104, 101, 108, 108, 111, -1]); @@ -91,10 +96,10 @@ async fn test_file_input_stream_skip_past_eof() -> Result<()> { let java_file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (file,)).await?; let fis = jvm.new_class("java/io/FileInputStream", "(Ljava/io/File;)V", (java_file,)).await?; - let skipped: i64 = jvm.invoke_virtual(&fis, "skip", "(J)J", (10i64,)).await?; + let skipped: i64 = jvm.invoke_virtual(&fis, &fis.class_definition().name(), "skip", "(J)J", (10i64,)).await?; assert_eq!(skipped, 5); - let read: i32 = jvm.invoke_virtual(&fis, "read", "()I", ()).await?; + let read: i32 = jvm.invoke_virtual(&fis, &fis.class_definition().name(), "read", "()I", ()).await?; assert_eq!(read, -1); Ok(()) diff --git a/java_runtime/tests/classes/java/io/test_file_reader_writer.rs b/java_runtime/tests/classes/java/io/test_file_reader_writer.rs index 432ec1f3..d86816fd 100644 --- a/java_runtime/tests/classes/java/io/test_file_reader_writer.rs +++ b/java_runtime/tests/classes/java/io/test_file_reader_writer.rs @@ -292,17 +292,29 @@ async fn file_01_file_reader_constructor_contracts() -> Result<()> { let path = JavaLangString::from_rust_string(&jvm, "input.txt").await?; let reader = jvm.new_class("java/io/FileReader", "(Ljava/lang/String;)V", (path.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'A' as i32); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + 'A' as i32 + ); let file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (path.clone(),)).await?; let reader = jvm.new_class("java/io/FileReader", "(Ljava/io/File;)V", (file.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'A' as i32); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + 'A' as i32 + ); let input = jvm.new_class("java/io/FileInputStream", "(Ljava/io/File;)V", (file,)).await?; let descriptor: ClassInstanceRef = jvm.get_field(&input, "fd", "Ljava/io/FileDescriptor;").await?; let reader = jvm.new_class("java/io/FileReader", "(Ljava/io/FileDescriptor;)V", (descriptor,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'A' as i32); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + 'A' as i32 + ); let null_path: ClassInstanceRef = None.into(); let result = jvm.new_class("java/io/FileReader", "(Ljava/lang/String;)V", (null_path,)).await; @@ -322,11 +334,15 @@ async fn file_02_file_03_file_writer_constructor_and_append_contracts() -> Resul let writer = jvm.new_class("java/io/FileWriter", "(Ljava/lang/String;)V", (path.clone(),)).await?; let value = JavaLangString::from_rust_string(&jvm, "new").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; assert_eq!(&*runtime.files.lock().unwrap()["output.txt"].lock().unwrap(), b"new"); let value = JavaLangString::from_rust_string(&jvm, "!").await?; - let closed: Result<()> = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await; + let closed: Result<()> = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("write after close must throw IOException"); }; @@ -335,16 +351,20 @@ async fn file_02_file_03_file_writer_constructor_and_append_contracts() -> Resul let file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (path.clone(),)).await?; let writer = jvm.new_class("java/io/FileWriter", "(Ljava/io/File;Z)V", (file.clone(), true)).await?; let value = JavaLangString::from_rust_string(&jvm, "+file").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; assert_eq!(&*runtime.files.lock().unwrap()["output.txt"].lock().unwrap(), b"new+file"); let writer = jvm .new_class("java/io/FileWriter", "(Ljava/lang/String;Z)V", (path.clone(), true)) .await?; let value = JavaLangString::from_rust_string(&jvm, "+path").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; assert_eq!(&*runtime.files.lock().unwrap()["output.txt"].lock().unwrap(), b"new+file+path"); let first = jvm @@ -355,10 +375,12 @@ async fn file_02_file_03_file_writer_constructor_and_append_contracts() -> Resul .await?; for (writer, text) in [(&first, "+first"), (&second, "+second"), (&first, "+third"), (&second, "+fourth")] { let value = JavaLangString::from_rust_string(&jvm, text).await?; - let _: () = jvm.invoke_virtual(writer, "write", "(Ljava/lang/String;)V", (value,)).await?; + let _: () = jvm + .invoke_virtual(writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; } - let _: () = jvm.invoke_virtual(&first, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&second, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&first, &first.class_definition().name(), "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&second, &second.class_definition().name(), "close", "()V", ()).await?; assert_eq!( &*runtime.files.lock().unwrap()["output.txt"].lock().unwrap(), b"new+file+path+first+second+third+fourth" @@ -366,8 +388,10 @@ async fn file_02_file_03_file_writer_constructor_and_append_contracts() -> Resul let writer = jvm.new_class("java/io/FileWriter", "(Ljava/io/File;)V", (file.clone(),)).await?; let value = JavaLangString::from_rust_string(&jvm, "reset").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; assert_eq!(&*runtime.files.lock().unwrap()["output.txt"].lock().unwrap(), b"reset"); let output = jvm.new_class("java/io/FileOutputStream", "(Ljava/io/File;)V", (file,)).await?; @@ -375,8 +399,10 @@ async fn file_02_file_03_file_writer_constructor_and_append_contracts() -> Resul jvm.get_field(&output, "fd", "Ljava/io/FileDescriptor;").await?; let writer = jvm.new_class("java/io/FileWriter", "(Ljava/io/FileDescriptor;)V", (descriptor,)).await?; let value = JavaLangString::from_rust_string(&jvm, "F").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; assert_eq!(&*runtime.files.lock().unwrap()["output.txt"].lock().unwrap(), b"F"); let null_path: ClassInstanceRef = None.into(); @@ -578,8 +604,10 @@ async fn file_writer_uses_only_opened_handle_write_semantics() -> Result<()> { let path = JavaLangString::from_rust_string(&jvm, "truncate.txt").await?; let writer = jvm.new_class("java/io/FileWriter", "(Ljava/lang/String;)V", (path,)).await?; let value = JavaLangString::from_rust_string(&jvm, "new").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; assert_eq!(&*runtime.files.lock().unwrap()["truncate.txt"].lock().unwrap(), b"new"); assert_eq!(runtime.seek_calls.load(Ordering::SeqCst), 0); @@ -605,7 +633,9 @@ async fn file_writer_uses_only_opened_handle_write_semantics() -> Result<()> { let second = jvm.new_class("java/io/FileWriter", "(Ljava/lang/String;Z)V", (path, true)).await?; for (writer, text) in [(&first, "-a"), (&second, "-b"), (&first, "-c"), (&second, "-d")] { let value = JavaLangString::from_rust_string(&jvm, text).await?; - let _: () = jvm.invoke_virtual(writer, "write", "(Ljava/lang/String;)V", (value,)).await?; + let _: () = jvm + .invoke_virtual(writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; } assert_eq!(&*runtime.files.lock().unwrap()["append.txt"].lock().unwrap(), b"start-a-b-c-d"); assert_eq!(runtime.seek_calls.load(Ordering::SeqCst), 0); @@ -625,12 +655,15 @@ async fn formatter_file_constructor_truncates_before_writing() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - let _: () = jvm.invoke_virtual(&formatter, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "close", "()V", ()) + .await?; assert_eq!(&*runtime.files.lock().unwrap()["formatter.txt"].lock().unwrap(), b"new"); assert_eq!( @@ -656,7 +689,9 @@ async fn file_writers_retry_partial_runtime_writes_until_complete() -> Result<() let output = jvm.new_class("java/io/FileOutputStream", "(Ljava/io/File;)V", (file,)).await?; let mut bytes = jvm.instantiate_array("B", 4).await?; jvm.store_array(&mut bytes, 0, [b'F' as i8, b'O' as i8, b'S' as i8, b'!' as i8]).await?; - let _: () = jvm.invoke_virtual(&output, "write", "([BII)V", (bytes, 0, 4)).await?; + let _: () = jvm + .invoke_virtual(&output, &output.class_definition().name(), "write", "([BII)V", (bytes, 0, 4)) + .await?; assert_eq!(&*runtime.files.lock().unwrap()["fos.bin"].lock().unwrap(), b"FOS!"); let mut runtime = MemoryRuntime::new([("raf.bin".into(), Vec::new())].into_iter().collect()); @@ -669,7 +704,9 @@ async fn file_writers_retry_partial_runtime_writes_until_complete() -> Result<() .await?; let mut bytes = jvm.instantiate_array("B", 4).await?; jvm.store_array(&mut bytes, 0, [b'R' as i8, b'A' as i8, b'F' as i8, b'!' as i8]).await?; - let _: () = jvm.invoke_virtual(&file, "write", "([BII)V", (bytes, 0, 4)).await?; + let _: () = jvm + .invoke_virtual(&file, &file.class_definition().name(), "write", "([BII)V", (bytes, 0, 4)) + .await?; assert_eq!(&*runtime.files.lock().unwrap()["raf.bin"].lock().unwrap(), b"RAF!"); let mut runtime = MemoryRuntime::new([("writer.txt".into(), Vec::new())].into_iter().collect()); @@ -678,7 +715,9 @@ async fn file_writers_retry_partial_runtime_writes_until_complete() -> Result<() let path = JavaLangString::from_rust_string(&jvm, "writer.txt").await?; let writer = jvm.new_class("java/io/FileWriter", "(Ljava/lang/String;)V", (path,)).await?; let value = JavaLangString::from_rust_string(&jvm, "A한B").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; assert_eq!(&*runtime.files.lock().unwrap()["writer.txt"].lock().unwrap(), "A한B".as_bytes()); Ok(()) @@ -697,7 +736,9 @@ async fn file_output_stream_reports_zero_and_late_write_failures_with_exact_pref let output = jvm.new_class("java/io/FileOutputStream", "(Ljava/io/File;)V", (file,)).await?; let mut bytes = jvm.instantiate_array("B", 3).await?; jvm.store_array(&mut bytes, 0, [b'a' as i8, b'b' as i8, b'c' as i8]).await?; - let result: Result<()> = jvm.invoke_virtual(&output, "write", "([BII)V", (bytes, 0, 3)).await; + let result: Result<()> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "write", "([BII)V", (bytes, 0, 3)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("incomplete runtime write must throw IOException"); }; @@ -711,7 +752,9 @@ async fn file_output_stream_reports_zero_and_late_write_failures_with_exact_pref let path = JavaLangString::from_rust_string(&jvm, "byte.bin").await?; let file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (path,)).await?; let output = jvm.new_class("java/io/FileOutputStream", "(Ljava/io/File;)V", (file,)).await?; - let result: Result<()> = jvm.invoke_virtual(&output, "write", "(I)V", (65,)).await; + let result: Result<()> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "write", "(I)V", (65,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("zero-byte runtime write must throw IOException"); }; @@ -736,7 +779,9 @@ async fn random_access_file_reports_zero_and_late_write_failures_with_exact_pref .await?; let mut bytes = jvm.instantiate_array("B", 3).await?; jvm.store_array(&mut bytes, 0, [b'a' as i8, b'b' as i8, b'c' as i8]).await?; - let result: Result<()> = jvm.invoke_virtual(&file, "write", "([BII)V", (bytes, 0, 3)).await; + let result: Result<()> = jvm + .invoke_virtual(&file, &file.class_definition().name(), "write", "([BII)V", (bytes, 0, 3)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("incomplete runtime write must throw IOException"); }; @@ -758,7 +803,9 @@ async fn file_writer_reports_zero_and_late_write_failures_with_exact_prefix() -> let path_string = JavaLangString::from_rust_string(&jvm, path).await?; let writer = jvm.new_class("java/io/FileWriter", "(Ljava/lang/String;)V", (path_string,)).await?; let value = JavaLangString::from_rust_string(&jvm, "abc").await?; - let result: Result<()> = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await; + let result: Result<()> = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("incomplete runtime write must throw IOException"); }; diff --git a/java_runtime/tests/classes/java/io/test_input_stream_reader.rs b/java_runtime/tests/classes/java/io/test_input_stream_reader.rs index 94c1a640..ea56ad46 100644 --- a/java_runtime/tests/classes/java/io/test_input_stream_reader.rs +++ b/java_runtime/tests/classes/java/io/test_input_stream_reader.rs @@ -62,7 +62,7 @@ impl OneByteInputStream { return Ok(0); } - let value: i32 = jvm.invoke_virtual(&this, "read", "()I", ()).await?; + let value: i32 = jvm.invoke_virtual(&this, "OneByteInputStream", "read", "()I", ()).await?; if value == -1 { return Ok(-1); } @@ -83,13 +83,17 @@ async fn test_isr() -> Result<()> { let isr = jvm.new_class("java/io/InputStreamReader", "(Ljava/io/InputStream;)V", (is,)).await?; let buf = jvm.instantiate_array("C", 10).await?; - let read: i32 = jvm.invoke_virtual(&isr, "read", "([CII)I", (buf.clone(), 0, 5)).await?; + let read: i32 = jvm + .invoke_virtual(&isr, &isr.class_definition().name(), "read", "([CII)I", (buf.clone(), 0, 5)) + .await?; assert_eq!(read, 5); let buf_data: Vec = jvm.load_array(&buf, 0, 5).await?; assert_eq!(buf_data, vec![72, 101, 108, 108, 111]); - let read: i32 = jvm.invoke_virtual(&isr, "read", "([CII)I", (buf.clone(), 0, 6)).await?; + let read: i32 = jvm + .invoke_virtual(&isr, &isr.class_definition().name(), "read", "([CII)I", (buf.clone(), 0, 6)) + .await?; assert_eq!(read, 6); let buf_data: Vec = jvm.load_array(&buf, 0, 6).await?; @@ -108,12 +112,22 @@ async fn test_input_stream_reader_preserves_split_multibyte_and_buffered_eof() - let reader = jvm.new_class("java/io/InputStreamReader", "(Ljava/io/InputStream;)V", (input,)).await?; let chars = jvm.instantiate_array("C", 16).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 0, 1)).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 1, 15)).await?, 9); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([CII)I", (chars.clone(), 0, 1)) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([CII)I", (chars.clone(), 1, 15)) + .await?, + 9 + ); let decoded: Vec = jvm.load_array(&chars, 0, 10).await?; assert_eq!(alloc::string::String::from_utf16(&decoded).unwrap(), value); - let invalid: Result = jvm.invoke_virtual(&reader, "read", "([CII)I", (chars, -1, 1)).await; + let invalid: Result = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "read", "([CII)I", (chars, -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid else { panic!("invalid range must throw IndexOutOfBoundsException"); }; @@ -142,9 +156,17 @@ async fn test_input_stream_reader_does_not_return_zero_for_split_multibyte_input let reader = jvm.new_class("java/io/InputStreamReader", "(Ljava/io/InputStream;)V", (input,)).await?; let chars = jvm.instantiate_array("C", 1).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars.clone(), 0, 1)).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([CII)I", (chars.clone(), 0, 1)) + .await?, + 1 + ); assert_eq!(jvm.load_array::(&chars, 0, 1).await?, ['한' as JavaChar]); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (chars, 0, 1)).await?, -1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([CII)I", (chars, 0, 1)) + .await?, + -1 + ); Ok(()) } @@ -181,32 +203,56 @@ async fn test_reader_default_contract_and_lifecycle() -> Result<()> { let input = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (bytes,)).await?; let reader = jvm.new_class("java/io/InputStreamReader", "(Ljava/io/InputStream;)V", (input,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&reader, "ready", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&reader, &reader.class_definition().name(), "ready", "()Z", ()) + .await? + ); assert!(!jvm.invoke_special::<_, bool>(&reader, "java/io/Reader", "ready", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'a' as i32); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + 'a' as i32 + ); let chars = jvm.instantiate_array("C", 2).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([C)I", (chars.clone(),)).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([C)I", (chars.clone(),)) + .await?, + 2 + ); assert_eq!(jvm.load_array::(&chars, 0, 2).await?, ['b' as JavaChar, 'c' as JavaChar]); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, -1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + -1 + ); let empty = jvm.instantiate_array("C", 0).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "([CII)I", (empty, 0, 0)).await?, 0); - assert!(!jvm.invoke_virtual::<_, bool>(&reader, "markSupported", "()Z", ()).await?); - - let mark: Result<()> = jvm.invoke_virtual(&reader, "mark", "(I)V", (1,)).await; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "([CII)I", (empty, 0, 0)) + .await?, + 0 + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&reader, &reader.class_definition().name(), "markSupported", "()Z", ()) + .await? + ); + + let mark: Result<()> = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "mark", "(I)V", (1,)).await; let Err(JavaError::JavaException(exception)) = mark else { panic!("default mark must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); - let reset: Result<()> = jvm.invoke_virtual(&reader, "reset", "()V", ()).await; + let reset: Result<()> = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "reset", "()V", ()).await; let Err(JavaError::JavaException(exception)) = reset else { panic!("default reset must throw IOException"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); - let negative_skip: Result = jvm.invoke_virtual(&reader, "skip", "(J)J", (-1i64,)).await; + let negative_skip: Result = jvm + .invoke_virtual(&reader, &reader.class_definition().name(), "skip", "(J)J", (-1i64,)) + .await; let Err(JavaError::JavaException(exception)) = negative_skip else { panic!("negative skip must throw IllegalArgumentException"); }; @@ -216,10 +262,22 @@ async fn test_reader_default_contract_and_lifecycle() -> Result<()> { jvm.store_array(&mut bytes, 0, [b'x' as i8, b'y' as i8, b'z' as i8]).await?; let input = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (bytes,)).await?; let reader = jvm.new_class("java/io/InputStreamReader", "(Ljava/io/InputStream;)V", (input,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&reader, "skip", "(J)J", (2i64,)).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reader, "read", "()I", ()).await?, 'z' as i32); - assert_eq!(jvm.invoke_virtual::<_, i64>(&reader, "skip", "(J)J", (2i64,)).await?, 0); - let _: () = jvm.invoke_virtual(&reader, "close", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i64>(&reader, &reader.class_definition().name(), "skip", "(J)J", (2i64,)) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reader, &reader.class_definition().name(), "read", "()I", ()) + .await?, + 'z' as i32 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&reader, &reader.class_definition().name(), "skip", "(J)J", (2i64,)) + .await?, + 0 + ); + let _: () = jvm.invoke_virtual(&reader, &reader.class_definition().name(), "close", "()V", ()).await?; let null_lock: ClassInstanceRef = None.into(); let result: Result<()> = jvm diff --git a/java_runtime/tests/classes/java/io/test_output_stream_close.rs b/java_runtime/tests/classes/java/io/test_output_stream_close.rs index 06e38bd3..ce23f754 100644 --- a/java_runtime/tests/classes/java/io/test_output_stream_close.rs +++ b/java_runtime/tests/classes/java/io/test_output_stream_close.rs @@ -146,8 +146,12 @@ async fn buffered_output_stream_inherited_close_dispatches_virtual_flush() -> Re .into(); let buffer: ClassInstanceRef> = jvm.get_field(&stream, "buf", "[B").await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (7,)).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, "FlushOverrideBufferedOutputStream", "write", "(I)V", (7,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, "FlushOverrideBufferedOutputStream", "close", "()V", ()) + .await?; assert_eq!(jvm.get_field::(&stream, "flushCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&backing, "bytesWritten", "I").await?, 1); @@ -159,7 +163,9 @@ async fn buffered_output_stream_inherited_close_dispatches_virtual_flush() -> Re let closed_output: ClassInstanceRef = jvm.get_field(&stream, "out", "Ljava/io/OutputStream;").await?; assert!(closed_output.is_null()); - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, "FlushOverrideBufferedOutputStream", "close", "()V", ()) + .await?; assert_eq!(jvm.get_field::(&stream, "flushCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&backing, "closeCalls", "I").await?, 1); Ok(()) @@ -175,8 +181,12 @@ async fn filter_output_stream_close_preserves_failure_sequence_and_state() -> Re .new_class("FlushOverrideBufferedOutputStream", "(Ljava/io/OutputStream;II)V", (output, 4, 1)) .await? .into(); - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (1,)).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, "FlushOverrideBufferedOutputStream", "write", "(I)V", (1,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, "FlushOverrideBufferedOutputStream", "close", "()V", ()) + .await?; assert_eq!(jvm.get_field::(&stream, "flushCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&stream, "count", "I").await?, 1); assert_eq!(jvm.get_field::(&backing, "bytesWritten", "I").await?, 0); @@ -190,7 +200,7 @@ async fn filter_output_stream_close_preserves_failure_sequence_and_state() -> Re .new_class("FlushOverrideBufferedOutputStream", "(Ljava/io/OutputStream;II)V", (output, 4, 2)) .await? .into(); - let result: Result<()> = jvm.invoke_virtual(&stream, "close", "()V", ()).await; + let result: Result<()> = jvm.invoke_virtual(&stream, "FlushOverrideBufferedOutputStream", "close", "()V", ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("unchecked flush failure must escape inherited close"); }; @@ -205,8 +215,10 @@ async fn filter_output_stream_close_preserves_failure_sequence_and_state() -> Re .new_class("FlushOverrideBufferedOutputStream", "(Ljava/io/OutputStream;II)V", (output, 4, 0)) .await? .into(); - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (1,)).await?; - let result: Result<()> = jvm.invoke_virtual(&stream, "close", "()V", ()).await; + let _: () = jvm + .invoke_virtual(&stream, "FlushOverrideBufferedOutputStream", "write", "(I)V", (1,)) + .await?; + let result: Result<()> = jvm.invoke_virtual(&stream, "FlushOverrideBufferedOutputStream", "close", "()V", ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("backing close failure must escape inherited close"); }; diff --git a/java_runtime/tests/classes/java/io/test_output_stream_writer.rs b/java_runtime/tests/classes/java/io/test_output_stream_writer.rs index 07449790..1f03412c 100644 --- a/java_runtime/tests/classes/java/io/test_output_stream_writer.rs +++ b/java_runtime/tests/classes/java/io/test_output_stream_writer.rs @@ -19,10 +19,14 @@ async fn test_output_stream_writer_utf8() -> Result<()> { .await?; let value = JavaLangString::from_rust_string(&jvm, "A한😀").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (value,)).await?; - let _: () = jvm.invoke_virtual(&writer, "flush", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(Ljava/lang/String;)V", (value,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "flush", "()V", ()).await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toByteArray", "()[B", ()) + .await?; let length = jvm.array_length(&bytes).await?; let actual: Vec = jvm.load_array(&bytes, 0, length).await?; assert_eq!(actual, "A한😀".as_bytes().iter().map(|value| *value as i8).collect::>()); @@ -38,11 +42,17 @@ async fn test_output_stream_writer_preserves_surrogate_across_writes() -> Result .new_class("java/io/OutputStreamWriter", "(Ljava/io/OutputStream;)V", (output.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", (0xd83d,)).await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", (0xde00,)).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(I)V", (0xd83d,)) + .await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(I)V", (0xde00,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toByteArray", "()[B", ()) + .await?; let actual: Vec = jvm.load_array(&bytes, 0, jvm.array_length(&bytes).await?).await?; assert_eq!(actual, "😀".as_bytes().iter().map(|value| *value as i8).collect::>()); @@ -50,10 +60,14 @@ async fn test_output_stream_writer_preserves_surrogate_across_writes() -> Result let writer = jvm .new_class("java/io/OutputStreamWriter", "(Ljava/io/OutputStream;)V", (output.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", (0xd83d,)).await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer, &writer.class_definition().name(), "write", "(I)V", (0xd83d,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, &writer.class_definition().name(), "close", "()V", ()).await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, &output.class_definition().name(), "toByteArray", "()[B", ()) + .await?; assert_eq!(jvm.load_array::(&bytes, 0, jvm.array_length(&bytes).await?).await?, [b'?' as i8]); Ok(()) diff --git a/java_runtime/tests/classes/java/io/test_print_stream.rs b/java_runtime/tests/classes/java/io/test_print_stream.rs index b28a5f66..d64d3a15 100644 --- a/java_runtime/tests/classes/java/io/test_print_stream.rs +++ b/java_runtime/tests/classes/java/io/test_print_stream.rs @@ -97,7 +97,8 @@ impl ProbeOutputStream { } let content: ClassInstanceRef = jvm.get_field(&this, "content", "Ljava/io/ByteArrayOutputStream;").await?; - jvm.invoke_virtual(&content, "write", "(I)V", (value,)).await + jvm.invoke_virtual(&content, "java/io/ByteArrayOutputStream", "write", "(I)V", (value,)) + .await } async fn flush(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result<()> { @@ -236,7 +237,7 @@ impl PrintStreamRunner { jvm.put_field(&mut this, "started", "Z", true).await?; let stream: ClassInstanceRef = jvm.get_field(&this, "stream", "Ljava/io/PrintStream;").await?; let value: i32 = jvm.get_field(&this, "value", "I").await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(I)V", (value,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(I)V", (value,)).await?; jvm.put_field(&mut this, "done", "Z", true).await } } @@ -272,7 +273,7 @@ impl PrintStreamCloseRunner { async fn run(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result<()> { jvm.put_field(&mut this, "started", "Z", true).await?; let stream: ClassInstanceRef = jvm.get_field(&this, "stream", "Ljava/io/PrintStream;").await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "close", "()V", ()).await?; jvm.put_field(&mut this, "done", "Z", true).await } } @@ -414,7 +415,7 @@ async fn ps_02_auto_flush_matches_public_write_and_println_contracts() -> Result .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;Z)V", (output.clone(), true)) .await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", ('x' as i32,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "write", "(I)V", ('x' as i32,)).await?; assert_eq!(jvm.get_field::(&output, "flushCount", "I").await?, 0); let formatted_output = jvm.new_class("ProbeOutputStream", "(III)V", (0, 0, 0)).await?; @@ -428,6 +429,7 @@ async fn ps_02_auto_flush_matches_public_write_and_println_contracts() -> Result let _: ClassInstanceRef = jvm .invoke_virtual( &formatted_stream, + &formatted_stream.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;", (format, arguments), @@ -437,30 +439,40 @@ async fn ps_02_auto_flush_matches_public_write_and_println_contracts() -> Result assert!(format_writes > 0); assert_eq!(jvm.get_field::(&formatted_output, "flushCount", "I").await?, 1); - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", ('\n' as i32,)).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "write", "(I)V", ('\n' as i32,)) + .await?; assert_eq!(jvm.get_field::(&output, "flushCount", "I").await?, 1); let mut bytes = jvm.instantiate_array("B", 2).await?; jvm.store_array(&mut bytes, 0, [b'a' as i8, b'b' as i8]).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "([BII)V", (bytes, 0, 2)).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "write", "([BII)V", (bytes, 0, 2)) + .await?; assert_eq!(jvm.get_field::(&output, "flushCount", "I").await?, 2); let text = JavaLangString::from_rust_string(&jvm, "s").await?; let object: ClassInstanceRef = text.clone().into(); let mut chars = jvm.instantiate_array("C", 1).await?; jvm.store_array(&mut chars, 0, ['c' as JavaChar]).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(Ljava/lang/Object;)V", (object,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(Ljava/lang/String;)V", (text,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(I)V", (1,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(J)V", (2i64,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(C)V", ('d' as JavaChar,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "([C)V", (chars,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(I)V", (3,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(I)V", (4,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(Z)V", (true,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(F)V", (1.5f32,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(D)V", (2.5f64,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", (object,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", (text,)) + .await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(I)V", (1,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(J)V", (2i64,)).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(C)V", ('d' as JavaChar,)) + .await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "([C)V", (chars,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(I)V", (3,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(I)V", (4,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(Z)V", (true,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(F)V", (1.5f32,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(D)V", (2.5f64,)).await?; assert!(jvm.get_field::(&output, "flushCount", "I").await? >= 14); let output = jvm.new_class("ProbeOutputStream", "(III)V", (0, 0, 0)).await?; @@ -469,11 +481,18 @@ async fn ps_02_auto_flush_matches_public_write_and_println_contracts() -> Result .await?; let mut bytes = jvm.instantiate_array("B", 1).await?; jvm.store_array(&mut bytes, 0, [b'\n' as i8]).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", ('\n' as i32,)).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "([BII)V", (bytes, 0, 1)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "write", "(I)V", ('\n' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "write", "([BII)V", (bytes, 0, 1)) + .await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "()V", ()).await?; assert_eq!(jvm.get_field::(&output, "flushCount", "I").await?, 0); - assert!(!jvm.invoke_virtual::<_, bool>(&stream, "checkError", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&stream, "java/io/PrintStream", "checkError", "()Z", ()) + .await? + ); assert_eq!(jvm.get_field::(&output, "flushCount", "I").await?, 1); Ok(()) @@ -509,9 +528,13 @@ async fn ps_02_uses_default_encoding_split_surrogate_state_and_line_separator() .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (output.clone(),)) .await?; let value = JavaLangString::from_rust_string(&jvm, "ê°€").await?; - let _: () = jvm.invoke_virtual(&stream, "print", "(Ljava/lang/String;)V", (value,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "()V", ()).await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", (value,)) + .await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "()V", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; assert_eq!( jvm.load_array::(&bytes, 0, jvm.array_length(&bytes).await?).await?, [0xb0u8 as i8, 0xa1u8 as i8, b'\r' as i8, b'\n' as i8] @@ -531,11 +554,19 @@ async fn ps_02_uses_default_encoding_split_surrogate_state_and_line_separator() let stream = jvm .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (output.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&stream, "print", "(C)V", (0xd83d as JavaChar,)).await?; - let pending: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "print", "(C)V", (0xd83d as JavaChar,)) + .await?; + let pending: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; assert_eq!(jvm.array_length(&pending).await?, 0); - let _: () = jvm.invoke_virtual(&stream, "print", "(C)V", (0xde00 as JavaChar,)).await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "print", "(C)V", (0xde00 as JavaChar,)) + .await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; assert_eq!( jvm.load_array::(&bytes, 0, jvm.array_length(&bytes).await?).await?, [0xf0u8 as i8, 0x9fu8 as i8, 0x98u8 as i8, 0x80u8 as i8] @@ -552,11 +583,13 @@ async fn ps_02_typed_println_is_atomic_and_preserves_virtual_dispatch() -> Resul let stream = jvm .new_class("OverridePrintStream", "(Ljava/io/OutputStream;)V", (output.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(I)V", (7,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(I)V", (7,)).await?; assert_eq!(jvm.get_field::(&stream, "printCount", "I").await?, 1); assert_eq!(jvm.get_field::(&stream, "printlnCount", "I").await?, 0); assert!(jvm.get_field::(&stream, "writeCount", "I").await? >= 2); - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; assert_eq!( jvm.load_array::(&bytes, 0, jvm.array_length(&bytes).await?).await?, b"<7>\n".iter().map(|value| *value as i8).collect::>() @@ -581,7 +614,9 @@ async fn ps_02_typed_println_is_atomic_and_preserves_virtual_dispatch() -> Resul .new_class("java/lang/Thread", "(Ljava/lang/Runnable;)V", (second_runner.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&first_thread, "start", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&first_thread, &first_thread.class_definition().name(), "start", "()V", ()) + .await?; let mut first_write_entered = false; for _ in 0..1000 { first_write_entered = jvm.get_field::(&blocking_output, "firstWriteEntered", "Z").await?; @@ -592,7 +627,9 @@ async fn ps_02_typed_println_is_atomic_and_preserves_virtual_dispatch() -> Resul } assert!(first_write_entered, "first println did not reach its backing write"); - let _: () = jvm.invoke_virtual(&second_thread, "start", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&second_thread, &second_thread.class_definition().name(), "start", "()V", ()) + .await?; let mut second_started = false; for _ in 0..1000 { second_started = jvm.get_field::(&second_runner, "started", "Z").await?; @@ -607,10 +644,16 @@ async fn ps_02_typed_println_is_atomic_and_preserves_virtual_dispatch() -> Resul assert!(!jvm.get_field::(&second_runner, "done", "Z").await?); jvm.put_field(&mut blocking_output, "releaseFirstWrite", "Z", true).await?; - let _: () = jvm.invoke_virtual(&first_thread, "join", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&second_thread, "join", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&first_thread, &first_thread.class_definition().name(), "join", "()V", ()) + .await?; + let _: () = jvm + .invoke_virtual(&second_thread, &second_thread.class_definition().name(), "join", "()V", ()) + .await?; let content: ClassInstanceRef = jvm.get_field(&blocking_output, "content", "Ljava/io/ByteArrayOutputStream;").await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&content, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&content, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; assert_eq!( jvm.load_array::(&bytes, 0, jvm.array_length(&bytes).await?).await?, b"1\n2\n".iter().map(|value| *value as i8).collect::>() @@ -637,7 +680,9 @@ async fn ps_02_write_and_close_are_serialized_on_the_stream_monitor() -> Result< let writer_thread = jvm.new_class("java/lang/Thread", "(Ljava/lang/Runnable;)V", (writer,)).await?; let close_thread = jvm.new_class("java/lang/Thread", "(Ljava/lang/Runnable;)V", (closer.clone(),)).await?; - let _: () = jvm.invoke_virtual(&writer_thread, "start", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer_thread, &writer_thread.class_definition().name(), "start", "()V", ()) + .await?; let mut first_write_entered = false; for _ in 0..1000 { first_write_entered = jvm.get_field::(&output, "firstWriteEntered", "Z").await?; @@ -648,7 +693,9 @@ async fn ps_02_write_and_close_are_serialized_on_the_stream_monitor() -> Result< } assert!(first_write_entered); - let _: () = jvm.invoke_virtual(&close_thread, "start", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&close_thread, &close_thread.class_definition().name(), "start", "()V", ()) + .await?; let mut close_started = false; for _ in 0..1000 { close_started = jvm.get_field::(&closer, "started", "Z").await?; @@ -663,11 +710,17 @@ async fn ps_02_write_and_close_are_serialized_on_the_stream_monitor() -> Result< assert!(!jvm.get_field::(&closer, "done", "Z").await?); jvm.put_field(&mut output, "releaseFirstWrite", "Z", true).await?; - let _: () = jvm.invoke_virtual(&writer_thread, "join", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&close_thread, "join", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&writer_thread, &writer_thread.class_definition().name(), "join", "()V", ()) + .await?; + let _: () = jvm + .invoke_virtual(&close_thread, &close_thread.class_definition().name(), "join", "()V", ()) + .await?; assert_eq!(jvm.get_field::(&output, "closeCount", "I").await?, 1); let content: ClassInstanceRef = jvm.get_field(&output, "content", "Ljava/io/ByteArrayOutputStream;").await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&content, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&content, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; assert_eq!( jvm.load_array::(&bytes, 0, jvm.array_length(&bytes).await?).await?, b"1\n".iter().map(|value| *value as i8).collect::>() @@ -686,12 +739,19 @@ async fn ps_02_failure_phases_continue_like_jdk_and_nested_error_is_visible() -> .await? .into(); let value = JavaLangString::from_rust_string(&jvm, "V").await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(Ljava/lang/String;)V", (value,)).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", (value,)) + .await?; assert_eq!(jvm.get_field::(&value_failure, "writeCount", "I").await?, 2); let content: ClassInstanceRef = jvm.get_field(&value_failure, "content", "Ljava/io/ByteArrayOutputStream;").await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&content, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&content, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; assert_eq!(jvm.load_array::(&bytes, 0, 1).await?, [b'\n' as i8]); - assert!(jvm.invoke_virtual::<_, bool>(&stream, "checkError", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&stream, "java/io/PrintStream", "checkError", "()Z", ()) + .await? + ); assert_monitor_released(&jvm, &stream).await?; let newline_failure = jvm.new_class("ProbeOutputStream", "(III)V", (4, 0, 0)).await?; @@ -700,10 +760,15 @@ async fn ps_02_failure_phases_continue_like_jdk_and_nested_error_is_visible() -> .await? .into(); let value = JavaLangString::from_rust_string(&jvm, "V").await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(Ljava/lang/String;)V", (value,)).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", (value,)) + .await?; assert_eq!(jvm.get_field::(&newline_failure, "writeCount", "I").await?, 2); assert_eq!(jvm.get_field::(&newline_failure, "flushCount", "I").await?, 2); - assert!(jvm.invoke_virtual::<_, bool>(&stream, "checkError", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&stream, "java/io/PrintStream", "checkError", "()Z", ()) + .await? + ); let final_flush_failure = jvm.new_class("ProbeOutputStream", "(III)V", (0, 3, 0)).await?; let stream: ClassInstanceRef = jvm @@ -711,7 +776,9 @@ async fn ps_02_failure_phases_continue_like_jdk_and_nested_error_is_visible() -> .await? .into(); let value = JavaLangString::from_rust_string(&jvm, "V").await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(Ljava/lang/String;)V", (value,)).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", (value,)) + .await?; assert_eq!(jvm.get_field::(&final_flush_failure, "flushCount", "I").await?, 3); assert!(jvm.get_field::(&stream, "trouble", "Z").await?); @@ -721,7 +788,10 @@ async fn ps_02_failure_phases_continue_like_jdk_and_nested_error_is_visible() -> .await? .into(); let outer = jvm.new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (inner,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&outer, "checkError", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&outer, &outer.class_definition().name(), "checkError", "()Z", ()) + .await? + ); Ok(()) } @@ -732,7 +802,7 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { let io_failure = jvm.new_class("ProbeOutputStream", "(III)V", (1, 0, 0)).await?; let stream = jvm.new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (io_failure,)).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (1,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "write", "(I)V", (1,)).await?; assert!(jvm.get_field::(&stream, "trouble", "Z").await?); let stream: ClassInstanceRef = stream.into(); assert_monitor_released(&jvm, &stream).await?; @@ -742,7 +812,7 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (runtime_failure,)) .await? .into(); - let result: Result<()> = jvm.invoke_virtual(&stream, "write", "(I)V", (1,)).await; + let result: Result<()> = jvm.invoke_virtual(&stream, "java/io/PrintStream", "write", "(I)V", (1,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("non-IOException from write must propagate"); }; @@ -753,13 +823,17 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { let clean_output = jvm.new_class("ProbeOutputStream", "(III)V", (0, 0, 0)).await?; let stream = jvm.new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (clean_output,)).await?; let null_bytes: ClassInstanceRef> = None.into(); - let result: Result<()> = jvm.invoke_virtual(&stream, "write", "([BII)V", (null_bytes, 0, 0)).await; + let result: Result<()> = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "write", "([BII)V", (null_bytes, 0, 0)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("null byte array must throw NullPointerException"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); let bytes = jvm.instantiate_array("B", 1).await?; - let result: Result<()> = jvm.invoke_virtual(&stream, "write", "([BII)V", (bytes, 1, 1)).await; + let result: Result<()> = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "write", "([BII)V", (bytes, 1, 1)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("invalid byte range must throw IndexOutOfBoundsException"); }; @@ -770,7 +844,7 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { let stream = jvm .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (flush_failure,)) .await?; - let _: () = jvm.invoke_virtual(&stream, "flush", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "flush", "()V", ()).await?; assert!(jvm.get_field::(&stream, "trouble", "Z").await?); let runtime_flush_failure = jvm.new_class("ProbeOutputStream", "(III)V", (0, 2, 0)).await?; @@ -778,13 +852,13 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (runtime_flush_failure,)) .await? .into(); - let result: Result<()> = jvm.invoke_virtual(&stream, "flush", "()V", ()).await; + let result: Result<()> = jvm.invoke_virtual(&stream, "java/io/PrintStream", "flush", "()V", ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("non-IOException from flush must propagate"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalStateException")); assert_monitor_released(&jvm, &stream).await?; - let result: Result = jvm.invoke_virtual(&stream, "checkError", "()Z", ()).await; + let result: Result = jvm.invoke_virtual(&stream, "java/io/PrintStream", "checkError", "()Z", ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("checkError must propagate a non-IOException from flush"); }; @@ -796,8 +870,8 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (close_failure.clone(),)) .await? .into(); - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "close", "()V", ()).await?; assert_eq!(jvm.get_field::(&close_failure, "closeCount", "I").await?, 1); assert!(jvm.get_field::(&stream, "trouble", "Z").await?); assert!(jvm.get_field::(&stream, "closing", "Z").await?); @@ -812,7 +886,7 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (runtime_close_failure.clone(),)) .await? .into(); - let result: Result<()> = jvm.invoke_virtual(&stream, "close", "()V", ()).await; + let result: Result<()> = jvm.invoke_virtual(&stream, "java/io/PrintStream", "close", "()V", ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("non-IOException from close must propagate"); }; @@ -826,7 +900,7 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { assert!(!jvm.get_field::(&stream, "trouble", "Z").await?); assert_monitor_released(&jvm, &stream).await?; jvm.put_field(&mut runtime_close_failure, "closeMode", "I", 0).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "close", "()V", ()).await?; assert_eq!(jvm.get_field::(&runtime_close_failure, "closeCount", "I").await?, 1); let stored_output: ClassInstanceRef = jvm.get_field(&stream, "out", "Ljava/io/OutputStream;").await?; assert_eq!(stored_output.identity(), runtime_close_failure.identity()); @@ -837,8 +911,10 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (encoder_close_failure.clone(),)) .await? .into(); - let _: () = jvm.invoke_virtual(&stream, "print", "(C)V", (0xd83d as JavaChar,)).await?; - let result: Result<()> = jvm.invoke_virtual(&stream, "close", "()V", ()).await; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "print", "(C)V", (0xd83d as JavaChar,)) + .await?; + let result: Result<()> = jvm.invoke_virtual(&stream, "java/io/PrintStream", "close", "()V", ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("non-IOException from encoder close must propagate"); }; @@ -849,7 +925,7 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { assert!(!jvm.get_field::(&stream, "trouble", "Z").await?); assert_monitor_released(&jvm, &stream).await?; jvm.put_field(&mut encoder_close_failure, "writeMode", "I", 0).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "close", "()V", ()).await?; assert_eq!(jvm.get_field::(&encoder_close_failure, "writeCount", "I").await?, 1); assert_eq!(jvm.get_field::(&encoder_close_failure, "closeCount", "I").await?, 0); assert_monitor_released(&jvm, &stream).await?; @@ -858,10 +934,16 @@ async fn ps_02_suppresses_only_ioexception_and_closes_once() -> Result<()> { let stream = jvm .new_class("java/io/PrintStream", "(Ljava/io/OutputStream;)V", (closed_output.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; - assert!(!jvm.invoke_virtual::<_, bool>(&stream, "checkError", "()Z", ()).await?); - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", (1,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&stream, "checkError", "()Z", ()).await?); + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "close", "()V", ()).await?; + assert!( + !jvm.invoke_virtual::<_, bool>(&stream, "java/io/PrintStream", "checkError", "()Z", ()) + .await? + ); + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "write", "(I)V", (1,)).await?; + assert!( + jvm.invoke_virtual::<_, bool>(&stream, "java/io/PrintStream", "checkError", "()Z", ()) + .await? + ); assert_eq!(jvm.get_field::(&closed_output, "writeCount", "I").await?, 0); Ok(()) @@ -877,22 +959,31 @@ async fn test_print_stream_cldc_api() -> Result<()> { .await?; let prefix = JavaLangString::from_rust_string(&jvm, "v=").await?; - let _: () = jvm.invoke_virtual(&stream, "print", "(Ljava/lang/String;)V", (prefix,)).await?; - let _: () = jvm.invoke_virtual(&stream, "print", "(I)V", (7,)).await?; - let _: () = jvm.invoke_virtual(&stream, "print", "(C)V", (' ' as u16,)).await?; - let _: () = jvm.invoke_virtual(&stream, "print", "(Z)V", (true,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", (prefix,)) + .await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "print", "(I)V", (7,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "print", "(C)V", (' ' as u16,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "print", "(Z)V", (true,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "()V", ()).await?; let mut chars = jvm.instantiate_array("C", 2).await?; jvm.store_array(&mut chars, 0, ['O' as JavaChar, 'K' as JavaChar]).await?; - let _: () = jvm.invoke_virtual(&stream, "print", "([C)V", (chars,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(D)V", (1.5f64,)).await?; - let _: () = jvm.invoke_virtual(&stream, "print", "(F)V", (1.0f32,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(D)V", (f64::INFINITY,)).await?; - let _: () = jvm.invoke_virtual(&stream, "flush", "()V", ()).await?; - assert!(!jvm.invoke_virtual::<_, bool>(&stream, "checkError", "()Z", ()).await?); - - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "print", "([C)V", (chars,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(D)V", (1.5f64,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "print", "(F)V", (1.0f32,)).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(D)V", (f64::INFINITY,)) + .await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "flush", "()V", ()).await?; + assert!( + !jvm.invoke_virtual::<_, bool>(&stream, "java/io/PrintStream", "checkError", "()Z", ()) + .await? + ); + + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; let values: Vec = jvm.load_array(&bytes, 0, jvm.array_length(&bytes).await?).await?; let values = values.into_iter().map(|value| value as u8).collect::>(); assert_eq!(values, b"v=7 true\nOK1.5\n1.0Infinity\n"); @@ -913,31 +1004,46 @@ async fn test_print_stream_remaining_overloads_and_close() -> Result<()> { let null_object: ClassInstanceRef = None.into(); let null_string: ClassInstanceRef = None.into(); - let _: () = jvm.invoke_virtual(&stream, "print", "(Ljava/lang/Object;)V", (object.clone(),)).await?; - let _: () = jvm.invoke_virtual(&stream, "print", "(Ljava/lang/Object;)V", (null_object,)).await?; let _: () = jvm - .invoke_virtual(&stream, "print", "(Ljava/lang/String;)V", (null_string.clone(),)) + .invoke_virtual(&stream, "java/io/PrintStream", "print", "(Ljava/lang/Object;)V", (object.clone(),)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "print", "(Ljava/lang/Object;)V", (null_object,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", (null_string.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&stream, "print", "(J)V", (9i64,)).await?; - let _: () = jvm.invoke_virtual(&stream, "write", "(I)V", ('|' as i32,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "print", "(J)V", (9i64,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "write", "(I)V", ('|' as i32,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(Ljava/lang/Object;)V", (object,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(Ljava/lang/String;)V", (null_string,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(I)V", (-1,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(J)V", (2i64,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(C)V", ('A' as JavaChar,)).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", (object,)) + .await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", (null_string,)) + .await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(I)V", (-1,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(J)V", (2i64,)).await?; + let _: () = jvm + .invoke_virtual(&stream, "java/io/PrintStream", "println", "(C)V", ('A' as JavaChar,)) + .await?; let mut chars = jvm.instantiate_array("C", 2).await?; jvm.store_array(&mut chars, 0, ['B' as JavaChar, 'C' as JavaChar]).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "([C)V", (chars,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(I)V", (-3,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(I)V", (4,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(Z)V", (false,)).await?; - let _: () = jvm.invoke_virtual(&stream, "println", "(F)V", (2.5f32,)).await?; - let _: () = jvm.invoke_virtual(&stream, "close", "()V", ()).await?; - assert!(!jvm.invoke_virtual::<_, bool>(&stream, "checkError", "()Z", ()).await?); - - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "([C)V", (chars,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(I)V", (-3,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(I)V", (4,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(Z)V", (false,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "println", "(F)V", (2.5f32,)).await?; + let _: () = jvm.invoke_virtual(&stream, "java/io/PrintStream", "close", "()V", ()).await?; + assert!( + !jvm.invoke_virtual::<_, bool>(&stream, "java/io/PrintStream", "checkError", "()Z", ()) + .await? + ); + + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; let values: Vec = jvm.load_array(&bytes, 0, jvm.array_length(&bytes).await?).await?; assert_eq!( values.into_iter().map(|value| value as u8).collect::>(), diff --git a/java_runtime/tests/classes/java/io/test_print_writer.rs b/java_runtime/tests/classes/java/io/test_print_writer.rs index 56fa3d0c..bf6ff9ce 100644 --- a/java_runtime/tests/classes/java/io/test_print_writer.rs +++ b/java_runtime/tests/classes/java/io/test_print_writer.rs @@ -105,7 +105,13 @@ impl ProbeWriter { let content: ClassInstanceRef = jvm.get_field(&this, "content", "Ljava/lang/StringBuffer;").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&content, "append", "([CII)Ljava/lang/StringBuffer;", (chars, offset, length)) + .invoke_virtual( + &content, + "java/lang/StringBuffer", + "append", + "([CII)Ljava/lang/StringBuffer;", + (chars, offset, length), + ) .await?; Ok(()) } @@ -170,12 +176,14 @@ impl OverridePrintWriter { async fn print_int(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, value: i32) -> Result<()> { let value = JavaLangString::from_rust_string(jvm, &format!("<{value}>")).await?; - jvm.invoke_virtual(&this, "write", "(Ljava/lang/String;)V", (value,)).await + jvm.invoke_virtual(&this, "OverridePrintWriter", "write", "(Ljava/lang/String;)V", (value,)) + .await } async fn println(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef) -> Result<()> { let value = JavaLangString::from_rust_string(jvm, "").await?; - jvm.invoke_virtual(&this, "write", "(Ljava/lang/String;)V", (value,)).await + jvm.invoke_virtual(&this, "OverridePrintWriter", "write", "(Ljava/lang/String;)V", (value,)) + .await } } @@ -219,7 +227,7 @@ impl PrintWriterRunner { jvm.put_field(&mut this, "started", "Z", true).await?; let writer: ClassInstanceRef = jvm.get_field(&this, "writer", "Ljava/io/PrintWriter;").await?; let value: i32 = jvm.get_field(&this, "value", "I").await?; - let _: () = jvm.invoke_virtual(&writer, "println", "(I)V", (value,)).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/PrintWriter", "println", "(I)V", (value,)).await?; jvm.put_field(&mut this, "done", "Z", true).await } } @@ -255,7 +263,7 @@ impl PrintWriterCloseRunner { async fn run(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef) -> Result<()> { jvm.put_field(&mut this, "started", "Z", true).await?; let writer: ClassInstanceRef = jvm.get_field(&this, "writer", "Ljava/io/PrintWriter;").await?; - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/PrintWriter", "close", "()V", ()).await?; jvm.put_field(&mut this, "done", "Z", true).await } } @@ -418,10 +426,26 @@ async fn pw_01_constructors_fields_descriptors_and_access_flags() -> Result<()> assert!(!jvm.get_field::(&default_output_writer, "autoFlush", "Z").await?); let output_text = JavaLangString::from_rust_string(&jvm, "os").await?; let _: () = jvm - .invoke_virtual(&default_output_writer, "write", "(Ljava/lang/String;)V", (output_text,)) + .invoke_virtual( + &default_output_writer, + &default_output_writer.class_definition().name(), + "write", + "(Ljava/lang/String;)V", + (output_text,), + ) + .await?; + let _: () = jvm + .invoke_virtual( + &default_output_writer, + &default_output_writer.class_definition().name(), + "flush", + "()V", + (), + ) + .await?; + let output_bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) .await?; - let _: () = jvm.invoke_virtual(&default_output_writer, "flush", "()V", ()).await?; - let output_bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; assert_eq!(jvm.load_array::(&output_bytes, 0, 2).await?, [b'o' as i8, b's' as i8]); let null_writer: ClassInstanceRef = None.into(); @@ -451,26 +475,42 @@ async fn pw_02_write_overloads_suppress_only_ioexception() -> Result<()> { .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (string_writer.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", ('A' as i32,)).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/Writer", "write", "(I)V", ('A' as i32,)).await?; let mut chars = jvm.instantiate_array("C", 3).await?; jvm.store_array(&mut chars, 0, ['B' as JavaChar, 'C' as JavaChar, 'D' as JavaChar]) .await?; - let _: () = jvm.invoke_virtual(&writer, "write", "([C)V", (chars.clone(),)).await?; - let _: () = jvm.invoke_virtual(&writer, "write", "([CII)V", (chars.clone(), 1, 1)).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/Writer", "write", "([C)V", (chars.clone(),)).await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/Writer", "write", "([CII)V", (chars.clone(), 1, 1)) + .await?; let text = JavaLangString::from_rust_string(&jvm, "EFG").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (text.clone(),)).await?; let _: () = jvm - .invoke_virtual(&writer, "write", "(Ljava/lang/String;II)V", (text.clone(), 1, 1)) + .invoke_virtual(&writer, "java/io/Writer", "write", "(Ljava/lang/String;)V", (text.clone(),)) + .await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/Writer", "write", "(Ljava/lang/String;II)V", (text.clone(), 1, 1)) + .await?; + let result: ClassInstanceRef = jvm + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) .await?; - let result: ClassInstanceRef = jvm.invoke_virtual(&string_writer, "toString", "()Ljava/lang/String;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "ABCDCEFGF"); - let invalid_chars: Result<()> = jvm.invoke_virtual(&writer, "write", "([CII)V", (chars.clone(), -1, 1)).await; + let invalid_chars: Result<()> = jvm + .invoke_virtual(&writer, "java/io/Writer", "write", "([CII)V", (chars.clone(), -1, 1)) + .await; let Err(JavaError::JavaException(exception)) = invalid_chars else { panic!("invalid char range must throw IndexOutOfBoundsException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let invalid_string: Result<()> = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;II)V", (text, 2, 2)).await; + let invalid_string: Result<()> = jvm + .invoke_virtual(&writer, "java/io/Writer", "write", "(Ljava/lang/String;II)V", (text, 2, 2)) + .await; let Err(JavaError::JavaException(exception)) = invalid_string else { panic!("invalid String range must throw IndexOutOfBoundsException"); }; @@ -478,13 +518,15 @@ async fn pw_02_write_overloads_suppress_only_ioexception() -> Result<()> { assert!(!jvm.get_field::(&writer, "trouble", "Z").await?); let null_chars: ClassInstanceRef> = None.into(); - let null_chars_result: Result<()> = jvm.invoke_virtual(&writer, "write", "([C)V", (null_chars,)).await; + let null_chars_result: Result<()> = jvm.invoke_virtual(&writer, "java/io/Writer", "write", "([C)V", (null_chars,)).await; let Err(JavaError::JavaException(exception)) = null_chars_result else { panic!("null char array must throw NullPointerException"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); let null_string: ClassInstanceRef = None.into(); - let null_string_result: Result<()> = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (null_string,)).await; + let null_string_result: Result<()> = jvm + .invoke_virtual(&writer, "java/io/Writer", "write", "(Ljava/lang/String;)V", (null_string,)) + .await; let Err(JavaError::JavaException(exception)) = null_string_result else { panic!("null String must throw NullPointerException"); }; @@ -494,7 +536,9 @@ async fn pw_02_write_overloads_suppress_only_ioexception() -> Result<()> { let suppressing = jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (failing_writer.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&suppressing, "write", "(I)V", ('x' as i32,)).await?; + let _: () = jvm + .invoke_virtual(&suppressing, &suppressing.class_definition().name(), "write", "(I)V", ('x' as i32,)) + .await?; assert!(jvm.get_field::(&suppressing, "trouble", "Z").await?); assert_monitor_released(&jvm, &failing_writer).await?; @@ -502,7 +546,9 @@ async fn pw_02_write_overloads_suppress_only_ioexception() -> Result<()> { let propagating = jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (runtime_writer.clone(),)) .await?; - let runtime_result: Result<()> = jvm.invoke_virtual(&propagating, "write", "(I)V", ('x' as i32,)).await; + let runtime_result: Result<()> = jvm + .invoke_virtual(&propagating, &propagating.class_definition().name(), "write", "(I)V", ('x' as i32,)) + .await; let Err(JavaError::JavaException(exception)) = runtime_result else { panic!("user RuntimeException must propagate"); }; @@ -521,25 +567,43 @@ async fn pw_03_print_overloads_follow_string_value_of_and_null_rules() -> Result .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (string_writer.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&writer, "print", "(Z)V", (true,)).await?; - let _: () = jvm.invoke_virtual(&writer, "print", "(C)V", ('|' as JavaChar,)).await?; - let _: () = jvm.invoke_virtual(&writer, "print", "(I)V", (-2,)).await?; - let _: () = jvm.invoke_virtual(&writer, "print", "(J)V", (3i64,)).await?; - let _: () = jvm.invoke_virtual(&writer, "print", "(F)V", (1.5f32,)).await?; - let _: () = jvm.invoke_virtual(&writer, "print", "(D)V", (f64::INFINITY,)).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/PrintWriter", "print", "(Z)V", (true,)).await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/PrintWriter", "print", "(C)V", ('|' as JavaChar,)) + .await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/PrintWriter", "print", "(I)V", (-2,)).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/PrintWriter", "print", "(J)V", (3i64,)).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/PrintWriter", "print", "(F)V", (1.5f32,)).await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/PrintWriter", "print", "(D)V", (f64::INFINITY,)) + .await?; let mut chars = jvm.instantiate_array("C", 2).await?; jvm.store_array(&mut chars, 0, ['X' as JavaChar, 'Y' as JavaChar]).await?; - let _: () = jvm.invoke_virtual(&writer, "print", "([C)V", (chars,)).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/PrintWriter", "print", "([C)V", (chars,)).await?; let null_string: ClassInstanceRef = None.into(); - let _: () = jvm.invoke_virtual(&writer, "print", "(Ljava/lang/String;)V", (null_string,)).await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/PrintWriter", "print", "(Ljava/lang/String;)V", (null_string,)) + .await?; let object_string = JavaLangString::from_rust_string(&jvm, "obj").await?; let object: ClassInstanceRef = object_string.into(); - let _: () = jvm.invoke_virtual(&writer, "print", "(Ljava/lang/Object;)V", (object,)).await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/PrintWriter", "print", "(Ljava/lang/Object;)V", (object,)) + .await?; let null_object: ClassInstanceRef = None.into(); - let _: () = jvm.invoke_virtual(&writer, "print", "(Ljava/lang/Object;)V", (null_object,)).await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/PrintWriter", "print", "(Ljava/lang/Object;)V", (null_object,)) + .await?; - let result: ClassInstanceRef = jvm.invoke_virtual(&string_writer, "toString", "()Ljava/lang/String;", ()).await?; + let result: ClassInstanceRef = jvm + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "true|-231.5InfinityXYnullobjnull"); Ok(()) @@ -564,32 +628,48 @@ async fn pw_04_println_uses_line_separator_and_is_the_only_autoflush_path() -> R .new_class("java/io/PrintWriter", "(Ljava/io/Writer;Z)V", (probe.clone(), true)) .await?; let prefix = JavaLangString::from_rust_string(&jvm, "p").await?; - let _: () = jvm.invoke_virtual(&writer, "print", "(Ljava/lang/String;)V", (prefix,)).await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/PrintWriter", "print", "(Ljava/lang/String;)V", (prefix,)) + .await?; assert_eq!(jvm.get_field::(&probe, "flushCount", "I").await?, 0); let newline = JavaLangString::from_rust_string(&jvm, "\n").await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(Ljava/lang/String;)V", (newline,)).await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/Writer", "write", "(Ljava/lang/String;)V", (newline,)) + .await?; assert_eq!(jvm.get_field::(&probe, "flushCount", "I").await?, 0); - let _: () = jvm.invoke_virtual(&writer, "println", "(I)V", (7,)).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/PrintWriter", "println", "(I)V", (7,)).await?; assert_eq!(jvm.get_field::(&probe, "flushCount", "I").await?, 1); - let _: () = jvm.invoke_virtual(&writer, "println", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/PrintWriter", "println", "()V", ()).await?; assert_eq!(jvm.get_field::(&probe, "flushCount", "I").await?, 2); let content: ClassInstanceRef = jvm.get_field(&probe, "content", "Ljava/lang/StringBuffer;").await?; - let content: ClassInstanceRef = jvm.invoke_virtual(&content, "toString", "()Ljava/lang/String;", ()).await?; + let content: ClassInstanceRef = jvm + .invoke_virtual(&content, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &content).await?, "p\n7\r\n\r\n"); let no_flush_probe: ClassInstanceRef = jvm.new_class("ProbeWriter", "(III)V", (0, 0, 0)).await?.into(); let no_flush_writer = jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;Z)V", (no_flush_probe.clone(), false)) .await?; - let _: () = jvm.invoke_virtual(&no_flush_writer, "println", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&no_flush_writer, &no_flush_writer.class_definition().name(), "println", "()V", ()) + .await?; assert_eq!(jvm.get_field::(&no_flush_probe, "flushCount", "I").await?, 0); let newline_failure: ClassInstanceRef = jvm.new_class("ProbeWriter", "(III)V", (1, 0, 0)).await?.into(); let newline_failure_writer = jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;Z)V", (newline_failure.clone(), true)) .await?; - let _: () = jvm.invoke_virtual(&newline_failure_writer, "println", "()V", ()).await?; + let _: () = jvm + .invoke_virtual( + &newline_failure_writer, + &newline_failure_writer.class_definition().name(), + "println", + "()V", + (), + ) + .await?; assert_eq!(jvm.get_field::(&newline_failure, "writeCount", "I").await?, 1); assert_eq!(jvm.get_field::(&newline_failure, "flushCount", "I").await?, 0); assert!(jvm.get_field::(&newline_failure_writer, "trouble", "Z").await?); @@ -600,9 +680,17 @@ async fn pw_04_println_uses_line_separator_and_is_the_only_autoflush_path() -> R let fallback_writer = fallback_jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (fallback_output.clone(),)) .await?; - let _: () = fallback_jvm.invoke_virtual(&fallback_writer, "println", "()V", ()).await?; + let _: () = fallback_jvm + .invoke_virtual(&fallback_writer, &fallback_writer.class_definition().name(), "println", "()V", ()) + .await?; let fallback: ClassInstanceRef = fallback_jvm - .invoke_virtual(&fallback_output, "toString", "()Ljava/lang/String;", ()) + .invoke_virtual( + &fallback_output, + &fallback_output.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&fallback_jvm, &fallback).await?, "\n"); @@ -617,9 +705,13 @@ async fn pw_04_println_is_atomic_and_uses_java_virtual_dispatch() -> Result<()> let overriding_writer = jvm .new_class("OverridePrintWriter", "(Ljava/io/Writer;)V", (dispatch_probe.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&overriding_writer, "println", "(I)V", (7,)).await?; + let _: () = jvm + .invoke_virtual(&overriding_writer, &overriding_writer.class_definition().name(), "println", "(I)V", (7,)) + .await?; let dispatch_content: ClassInstanceRef = jvm.get_field(&dispatch_probe, "content", "Ljava/lang/StringBuffer;").await?; - let dispatch_content: ClassInstanceRef = jvm.invoke_virtual(&dispatch_content, "toString", "()Ljava/lang/String;", ()).await?; + let dispatch_content: ClassInstanceRef = jvm + .invoke_virtual(&dispatch_content, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &dispatch_content).await?, "<7>"); let mut blocking_probe: ClassInstanceRef = jvm.new_class("ProbeWriter", "(III)V", (0, 0, 0)).await?.into(); @@ -639,7 +731,9 @@ async fn pw_04_println_is_atomic_and_uses_java_virtual_dispatch() -> Result<()> .new_class("java/lang/Thread", "(Ljava/lang/Runnable;)V", (second_runner.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&first_thread, "start", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&first_thread, &first_thread.class_definition().name(), "start", "()V", ()) + .await?; let mut first_write_entered = false; for _ in 0..100 { first_write_entered = jvm.get_field::(&blocking_probe, "firstWriteEntered", "Z").await?; @@ -650,7 +744,9 @@ async fn pw_04_println_is_atomic_and_uses_java_virtual_dispatch() -> Result<()> } assert!(first_write_entered, "first println did not reach its backing write"); - let _: () = jvm.invoke_virtual(&second_thread, "start", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&second_thread, &second_thread.class_definition().name(), "start", "()V", ()) + .await?; let mut second_started = false; for _ in 0..100 { second_started = jvm.get_field::(&second_runner, "started", "Z").await?; @@ -669,13 +765,19 @@ async fn pw_04_println_is_atomic_and_uses_java_virtual_dispatch() -> Result<()> assert!(!jvm.get_field::(&second_runner, "done", "Z").await?); jvm.put_field(&mut blocking_probe, "releaseFirstWrite", "Z", true).await?; - let _: () = jvm.invoke_virtual(&first_thread, "join", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&second_thread, "join", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&first_thread, &first_thread.class_definition().name(), "join", "()V", ()) + .await?; + let _: () = jvm + .invoke_virtual(&second_thread, &second_thread.class_definition().name(), "join", "()V", ()) + .await?; assert!(jvm.get_field::(&first_runner, "done", "Z").await?); assert!(jvm.get_field::(&second_runner, "done", "Z").await?); let content: ClassInstanceRef = jvm.get_field(&blocking_probe, "content", "Ljava/lang/StringBuffer;").await?; - let content: ClassInstanceRef = jvm.invoke_virtual(&content, "toString", "()Ljava/lang/String;", ()).await?; + let content: ClassInstanceRef = jvm + .invoke_virtual(&content, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &content).await?, "1\n2\n"); let mut close_probe: ClassInstanceRef = jvm.new_class("ProbeWriter", "(III)V", (0, 0, 0)).await?.into(); @@ -697,7 +799,9 @@ async fn pw_04_println_is_atomic_and_uses_java_virtual_dispatch() -> Result<()> .new_class("java/lang/Thread", "(Ljava/lang/Runnable;)V", (second_close_runner.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&first_close_thread, "start", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&first_close_thread, &first_close_thread.class_definition().name(), "start", "()V", ()) + .await?; let mut first_close_entered = false; for _ in 0..100 { first_close_entered = jvm.get_field::(&close_probe, "firstCloseEntered", "Z").await?; @@ -708,7 +812,9 @@ async fn pw_04_println_is_atomic_and_uses_java_virtual_dispatch() -> Result<()> } assert!(first_close_entered, "first close did not reach the backing writer"); - let _: () = jvm.invoke_virtual(&second_close_thread, "start", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&second_close_thread, &second_close_thread.class_definition().name(), "start", "()V", ()) + .await?; let mut second_close_started = false; for _ in 0..100 { second_close_started = jvm.get_field::(&second_close_runner, "started", "Z").await?; @@ -723,8 +829,12 @@ async fn pw_04_println_is_atomic_and_uses_java_virtual_dispatch() -> Result<()> assert!(!jvm.get_field::(&second_close_runner, "done", "Z").await?); jvm.put_field(&mut close_probe, "releaseFirstClose", "Z", true).await?; - let _: () = jvm.invoke_virtual(&first_close_thread, "join", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&second_close_thread, "join", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&first_close_thread, &first_close_thread.class_definition().name(), "join", "()V", ()) + .await?; + let _: () = jvm + .invoke_virtual(&second_close_thread, &second_close_thread.class_definition().name(), "join", "()V", ()) + .await?; assert!(jvm.get_field::(&first_close_runner, "done", "Z").await?); assert!(jvm.get_field::(&second_close_runner, "done", "Z").await?); assert_eq!(jvm.get_field::(&close_probe, "closeCount", "I").await?, 1); @@ -742,11 +852,16 @@ async fn pw_05_flush_close_and_check_error_preserve_trouble_state() -> Result<() let flush_writer = jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (flush_failure.clone(),)) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&flush_writer, "checkError", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&flush_writer, &flush_writer.class_definition().name(), "checkError", "()Z", ()) + .await? + ); assert_eq!(jvm.get_field::(&flush_failure, "flushCount", "I").await?, 1); assert_monitor_released(&jvm, &flush_failure).await?; jvm.put_field(&mut flush_failure, "flushMode", "I", 0).await?; - let _: () = jvm.invoke_virtual(&flush_writer, "flush", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&flush_writer, &flush_writer.class_definition().name(), "flush", "()V", ()) + .await?; assert!(jvm.get_field::(&flush_writer, "trouble", "Z").await?); let nested_failure: ClassInstanceRef = jvm.new_class("ProbeWriter", "(III)V", (0, 1, 0)).await?.into(); @@ -755,13 +870,16 @@ async fn pw_05_flush_close_and_check_error_preserve_trouble_state() -> Result<() .await? .into(); let outer_writer = jvm.new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (inner_writer,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&outer_writer, "checkError", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&outer_writer, &outer_writer.class_definition().name(), "checkError", "()Z", ()) + .await? + ); let mut close_failure: ClassInstanceRef = jvm.new_class("ProbeWriter", "(III)V", (0, 0, 1)).await?.into(); let close_writer = jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (close_failure.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&close_writer, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&close_writer, "java/io/PrintWriter", "close", "()V", ()).await?; assert_eq!(jvm.get_field::(&close_failure, "closeCount", "I").await?, 1); let open_after_failure: ClassInstanceRef = jvm.get_field(&close_writer, "out", "Ljava/io/Writer;").await?; assert!(!open_after_failure.is_null()); @@ -769,8 +887,8 @@ async fn pw_05_flush_close_and_check_error_preserve_trouble_state() -> Result<() assert_monitor_released(&jvm, &close_failure).await?; jvm.put_field(&mut close_failure, "closeMode", "I", 0).await?; - let _: () = jvm.invoke_virtual(&close_writer, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&close_writer, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&close_writer, "java/io/PrintWriter", "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&close_writer, "java/io/PrintWriter", "close", "()V", ()).await?; assert_eq!(jvm.get_field::(&close_failure, "closeCount", "I").await?, 2); assert!(jvm.get_field::(&close_writer, "trouble", "Z").await?); let closed_out: ClassInstanceRef = jvm.get_field(&close_writer, "out", "Ljava/io/Writer;").await?; @@ -780,10 +898,19 @@ async fn pw_05_flush_close_and_check_error_preserve_trouble_state() -> Result<() let closed_writer = jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (closed_probe.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&closed_writer, "close", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&closed_writer, "write", "(I)V", ('x' as i32,)).await?; - let _: () = jvm.invoke_virtual(&closed_writer, "flush", "()V", ()).await?; - assert!(jvm.invoke_virtual::<_, bool>(&closed_writer, "checkError", "()Z", ()).await?); + let _: () = jvm + .invoke_virtual(&closed_writer, &closed_writer.class_definition().name(), "close", "()V", ()) + .await?; + let _: () = jvm + .invoke_virtual(&closed_writer, &closed_writer.class_definition().name(), "write", "(I)V", ('x' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&closed_writer, &closed_writer.class_definition().name(), "flush", "()V", ()) + .await?; + assert!( + jvm.invoke_virtual::<_, bool>(&closed_writer, &closed_writer.class_definition().name(), "checkError", "()Z", ()) + .await? + ); assert_eq!(jvm.get_field::(&closed_probe, "writeCount", "I").await?, 0); assert_eq!(jvm.get_field::(&closed_probe, "flushCount", "I").await?, 0); @@ -791,7 +918,9 @@ async fn pw_05_flush_close_and_check_error_preserve_trouble_state() -> Result<() let runtime_flush_writer = jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (runtime_flush.clone(),)) .await?; - let runtime_flush_result: Result<()> = jvm.invoke_virtual(&runtime_flush_writer, "flush", "()V", ()).await; + let runtime_flush_result: Result<()> = jvm + .invoke_virtual(&runtime_flush_writer, &runtime_flush_writer.class_definition().name(), "flush", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = runtime_flush_result else { panic!("flush RuntimeException must propagate"); }; @@ -802,7 +931,9 @@ async fn pw_05_flush_close_and_check_error_preserve_trouble_state() -> Result<() let runtime_close_writer = jvm .new_class("java/io/PrintWriter", "(Ljava/io/Writer;)V", (runtime_close.clone(),)) .await?; - let runtime_close_result: Result<()> = jvm.invoke_virtual(&runtime_close_writer, "close", "()V", ()).await; + let runtime_close_result: Result<()> = jvm + .invoke_virtual(&runtime_close_writer, &runtime_close_writer.class_definition().name(), "close", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = runtime_close_result else { panic!("close RuntimeException must propagate"); }; @@ -811,7 +942,9 @@ async fn pw_05_flush_close_and_check_error_preserve_trouble_state() -> Result<() assert!(!open_after_runtime.is_null()); assert_monitor_released(&jvm, &runtime_close).await?; jvm.put_field(&mut runtime_close, "closeMode", "I", 0).await?; - let _: () = jvm.invoke_virtual(&runtime_close_writer, "close", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&runtime_close_writer, &runtime_close_writer.class_definition().name(), "close", "()V", ()) + .await?; let closed_after_retry: ClassInstanceRef = jvm.get_field(&runtime_close_writer, "out", "Ljava/io/Writer;").await?; assert!(closed_after_retry.is_null()); diff --git a/java_runtime/tests/classes/java/io/test_random_access_file.rs b/java_runtime/tests/classes/java/io/test_random_access_file.rs index 0a037c11..9dcd20e8 100644 --- a/java_runtime/tests/classes/java/io/test_random_access_file.rs +++ b/java_runtime/tests/classes/java/io/test_random_access_file.rs @@ -17,7 +17,9 @@ async fn test_random_access_file() -> Result<()> { .await?; let buf = jvm.instantiate_array("B", 11).await?; - let read: i32 = jvm.invoke_virtual(&raf, "read", "([B)I", (buf.clone(),)).await?; + let read: i32 = jvm + .invoke_virtual(&raf, &raf.class_definition().name(), "read", "([B)I", (buf.clone(),)) + .await?; assert_eq!(read, 11); let mut rust_buf = vec![0; 11]; diff --git a/java_runtime/tests/classes/java/io/test_stream_locking.rs b/java_runtime/tests/classes/java/io/test_stream_locking.rs index 8b603cff..14c3cd4e 100644 --- a/java_runtime/tests/classes/java/io/test_stream_locking.rs +++ b/java_runtime/tests/classes/java/io/test_stream_locking.rs @@ -127,16 +127,20 @@ impl StreamOperationRunner { let target: ClassInstanceRef = jvm.get_field(&this, "target", "Ljava/lang/Object;").await?; match jvm.get_field::(&this, "operation", "I").await? { 0 => { - let _: i32 = jvm.invoke_virtual(&target, "read", "()I", ()).await?; + let _: i32 = jvm.invoke_virtual(&target, &target.class_definition().name(), "read", "()I", ()).await?; } 1 => { - let _: () = jvm.invoke_virtual(&target, "write", "(I)V", ('X' as i32,)).await?; + let _: () = jvm + .invoke_virtual(&target, &target.class_definition().name(), "write", "(I)V", ('X' as i32,)) + .await?; } 2 => { - let _: () = jvm.invoke_virtual(&target, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&target, &target.class_definition().name(), "close", "()V", ()).await?; } _ => { - let _: () = jvm.invoke_virtual(&target, "newLine", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&target, &target.class_definition().name(), "newLine", "()V", ()) + .await?; } } jvm.put_field(&mut this, "done", "Z", true).await @@ -183,7 +187,7 @@ async fn assert_worker_waits_for_lock(jvm: &Jvm, target: ClassInstanceRef(&runner, "started", "Z").await?; @@ -195,7 +199,7 @@ async fn assert_worker_waits_for_lock(jvm: &Jvm, target: ClassInstanceRef(&runner, "done", "Z").await?; jvm.monitor_exit(&lock).await?; - let _: () = jvm.invoke_virtual(&thread, "join", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&thread, &thread.class_definition().name(), "join", "()V", ()).await?; assert!(started, "worker thread did not start"); assert!(!completed_while_locked, "state operation did not synchronize on inherited lock"); @@ -215,9 +219,13 @@ async fn buffered_writer_preserves_state_and_closes_after_backing_failures() -> let lock: ClassInstanceRef = jvm.get_field(&writer, "lock", "Ljava/lang/Object;").await?; assert_eq!(lock.identity(), backing.identity()); - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", ('A' as i32,)).await?; - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", ('B' as i32,)).await?; - let failed_flush: Result<()> = jvm.invoke_virtual(&writer, "flush", "()V", ()).await; + let _: () = jvm + .invoke_virtual(&writer, "java/io/BufferedWriter", "write", "(I)V", ('A' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&writer, "java/io/BufferedWriter", "write", "(I)V", ('B' as i32,)) + .await?; + let failed_flush: Result<()> = jvm.invoke_virtual(&writer, "java/io/BufferedWriter", "flush", "()V", ()).await; let Err(JavaError::JavaException(exception)) = failed_flush else { panic!("backing write failure must escape BufferedWriter.flush"); }; @@ -226,20 +234,22 @@ async fn buffered_writer_preserves_state_and_closes_after_backing_failures() -> assert_eq!(jvm.get_field::(&backing, "written", "I").await?, 0); assert_monitor_released(&jvm, &lock).await?; - let _: () = jvm.invoke_virtual(&writer, "flush", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/BufferedWriter", "flush", "()V", ()).await?; assert_eq!(jvm.get_field::(&writer, "nextChar", "I").await?, 0); assert_eq!(jvm.get_field::(&backing, "written", "I").await?, 2); jvm.put_field(&mut backing, "failClose", "Z", true).await?; - let failed_close: Result<()> = jvm.invoke_virtual(&writer, "close", "()V", ()).await; + let failed_close: Result<()> = jvm.invoke_virtual(&writer, "java/io/BufferedWriter", "close", "()V", ()).await; let Err(JavaError::JavaException(exception)) = failed_close else { panic!("backing close failure must escape BufferedWriter.close"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); assert_eq!(jvm.get_field::(&backing, "closeCalls", "I").await?, 1); - let _: () = jvm.invoke_virtual(&writer, "close", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&writer, "java/io/BufferedWriter", "close", "()V", ()).await?; assert_eq!(jvm.get_field::(&backing, "closeCalls", "I").await?, 1); - let closed: Result<()> = jvm.invoke_virtual(&writer, "write", "(I)V", ('C' as i32,)).await; + let closed: Result<()> = jvm + .invoke_virtual(&writer, "java/io/BufferedWriter", "write", "(I)V", ('C' as i32,)) + .await; let Err(JavaError::JavaException(exception)) = closed else { panic!("BufferedWriter must remain closed after a backing close failure"); }; @@ -252,15 +262,19 @@ async fn buffered_writer_preserves_state_and_closes_after_backing_failures() -> .new_class("java/io/BufferedWriter", "(Ljava/io/Writer;I)V", (backing_writer, 4)) .await? .into(); - let _: () = jvm.invoke_virtual(&writer, "write", "(I)V", ('X' as i32,)).await?; - let failed_close: Result<()> = jvm.invoke_virtual(&writer, "close", "()V", ()).await; + let _: () = jvm + .invoke_virtual(&writer, "java/io/BufferedWriter", "write", "(I)V", ('X' as i32,)) + .await?; + let failed_close: Result<()> = jvm.invoke_virtual(&writer, "java/io/BufferedWriter", "close", "()V", ()).await; let Err(JavaError::JavaException(exception)) = failed_close else { panic!("close must report a buffered backing write failure"); }; assert!(jvm.is_instance(&*exception, "java/io/IOException")); assert_eq!(jvm.get_field::(&writer, "nextChar", "I").await?, 1); assert_eq!(jvm.get_field::(&backing, "closeCalls", "I").await?, 1); - let closed: Result<()> = jvm.invoke_virtual(&writer, "write", "(I)V", ('Y' as i32,)).await; + let closed: Result<()> = jvm + .invoke_virtual(&writer, "java/io/BufferedWriter", "write", "(I)V", ('Y' as i32,)) + .await; assert!(closed.is_err(), "BufferedWriter must close even when flushing during close fails"); Ok(()) @@ -273,7 +287,15 @@ async fn character_streams_release_inherited_locks_after_errors() -> Result<()> let value = JavaLangString::from_rust_string(&jvm, "abc").await?; let string_reader = jvm.new_class("java/io/StringReader", "(Ljava/lang/String;)V", (value,)).await?; let target = jvm.instantiate_array("C", 1).await?; - let invalid: Result = jvm.invoke_virtual(&string_reader, "read", "([CII)I", (target, -1, 1)).await; + let invalid: Result = jvm + .invoke_virtual( + &string_reader, + &string_reader.class_definition().name(), + "read", + "([CII)I", + (target, -1, 1), + ) + .await; assert!(invalid.is_err()); let lock: ClassInstanceRef = jvm.get_field(&string_reader, "lock", "Ljava/lang/Object;").await?; assert_eq!(lock.identity(), string_reader.identity()); @@ -282,7 +304,9 @@ async fn character_streams_release_inherited_locks_after_errors() -> Result<()> let chars = jvm.instantiate_array("C", 1).await?; let char_reader = jvm.new_class("java/io/CharArrayReader", "([C)V", (chars,)).await?; let target = jvm.instantiate_array("C", 1).await?; - let invalid: Result = jvm.invoke_virtual(&char_reader, "read", "([CII)I", (target, 2, 1)).await; + let invalid: Result = jvm + .invoke_virtual(&char_reader, &char_reader.class_definition().name(), "read", "([CII)I", (target, 2, 1)) + .await; assert!(invalid.is_err()); let lock: ClassInstanceRef = jvm.get_field(&char_reader, "lock", "Ljava/lang/Object;").await?; assert_eq!(lock.identity(), char_reader.identity()); @@ -290,7 +314,15 @@ async fn character_streams_release_inherited_locks_after_errors() -> Result<()> let char_writer = jvm.new_class("java/io/CharArrayWriter", "()V", ()).await?; let null_chars: ClassInstanceRef> = None.into(); - let invalid: Result<()> = jvm.invoke_virtual(&char_writer, "write", "([CII)V", (null_chars, 0, 1)).await; + let invalid: Result<()> = jvm + .invoke_virtual( + &char_writer, + &char_writer.class_definition().name(), + "write", + "([CII)V", + (null_chars, 0, 1), + ) + .await; assert!(invalid.is_err()); let lock: ClassInstanceRef = jvm.get_field(&char_writer, "lock", "Ljava/lang/Object;").await?; assert_eq!(lock.identity(), char_writer.identity()); @@ -321,20 +353,28 @@ async fn character_stream_operations_and_close_wait_for_inherited_locks() -> Res let lock: ClassInstanceRef = jvm.get_field(&string_reader, "lock", "Ljava/lang/Object;").await?; assert_worker_waits_for_lock(&jvm, string_reader.instance.clone().into(), lock.clone(), 0).await?; assert_worker_waits_for_lock(&jvm, string_reader.instance.clone().into(), lock, 2).await?; - let closed: Result = jvm.invoke_virtual(&string_reader, "read", "()I", ()).await; + let closed: Result = jvm + .invoke_virtual(&string_reader, &string_reader.class_definition().name(), "read", "()I", ()) + .await; assert!(closed.is_err()); let chars = jvm.instantiate_array("C", 1).await?; let char_reader: ClassInstanceRef = jvm.new_class("java/io/CharArrayReader", "([C)V", (chars,)).await?.into(); let lock: ClassInstanceRef = jvm.get_field(&char_reader, "lock", "Ljava/lang/Object;").await?; assert_worker_waits_for_lock(&jvm, char_reader.instance.clone().into(), lock, 2).await?; - let closed: Result = jvm.invoke_virtual(&char_reader, "read", "()I", ()).await; + let closed: Result = jvm + .invoke_virtual(&char_reader, &char_reader.class_definition().name(), "read", "()I", ()) + .await; assert!(closed.is_err()); let char_writer: ClassInstanceRef = jvm.new_class("java/io/CharArrayWriter", "()V", ()).await?.into(); let lock: ClassInstanceRef = jvm.get_field(&char_writer, "lock", "Ljava/lang/Object;").await?; assert_worker_waits_for_lock(&jvm, char_writer.instance.clone().into(), lock, 1).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&char_writer, "size", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&char_writer, &char_writer.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/io/test_string_writer.rs b/java_runtime/tests/classes/java/io/test_string_writer.rs index a8396f64..c2178718 100644 --- a/java_runtime/tests/classes/java/io/test_string_writer.rs +++ b/java_runtime/tests/classes/java/io/test_string_writer.rs @@ -16,23 +16,68 @@ async fn test_string_writer() -> Result<()> { jvm.store_array(&mut buf, 0, vec![b'a' as JavaChar, b'b' as JavaChar, b'c' as JavaChar]) .await?; - let _: () = jvm.invoke_virtual(&string_writer, "write", "([CII)V", (buf.clone(), 0, 3)).await?; + let _: () = jvm + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "write", + "([CII)V", + (buf.clone(), 0, 3), + ) + .await?; - let _: () = jvm.invoke_virtual(&string_writer, "write", "([CII)V", (buf.clone(), 1, 2)).await?; - let _: () = jvm.invoke_virtual(&string_writer, "write", "(I)V", ('d' as i32,)).await?; - let _: () = jvm.invoke_virtual(&string_writer, "write", "([C)V", (buf,)).await?; + let _: () = jvm + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "write", + "([CII)V", + (buf.clone(), 1, 2), + ) + .await?; + let _: () = jvm + .invoke_virtual(&string_writer, &string_writer.class_definition().name(), "write", "(I)V", ('d' as i32,)) + .await?; + let _: () = jvm + .invoke_virtual(&string_writer, &string_writer.class_definition().name(), "write", "([C)V", (buf,)) + .await?; let value = JavaLangString::from_rust_string(&jvm, "XYZ").await?; let _: () = jvm - .invoke_virtual(&string_writer, "write", "(Ljava/lang/String;)V", (value.clone(),)) + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "write", + "(Ljava/lang/String;)V", + (value.clone(),), + ) + .await?; + let _: () = jvm + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "write", + "(Ljava/lang/String;II)V", + (value, 1, 1), + ) + .await?; + let _: () = jvm + .invoke_virtual(&string_writer, &string_writer.class_definition().name(), "flush", "()V", ()) .await?; let _: () = jvm - .invoke_virtual(&string_writer, "write", "(Ljava/lang/String;II)V", (value, 1, 1)) + .invoke_virtual(&string_writer, &string_writer.class_definition().name(), "close", "()V", ()) .await?; - let _: () = jvm.invoke_virtual(&string_writer, "flush", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&string_writer, "close", "()V", ()).await?; - let string = jvm.invoke_virtual(&string_writer, "toString", "()Ljava/lang/String;", ()).await.unwrap(); + let string = jvm + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await + .unwrap(); let string = JavaLangString::to_rust_string(&jvm, &string).await?; diff --git a/java_runtime/tests/classes/java/lang/test_boolean.rs b/java_runtime/tests/classes/java/lang/test_boolean.rs index 7b7c3e83..4449c4b0 100644 --- a/java_runtime/tests/classes/java/lang/test_boolean.rs +++ b/java_runtime/tests/classes/java/lang/test_boolean.rs @@ -8,23 +8,38 @@ async fn test_boolean_string_constants_and_type() -> Result<()> { let jvm = test_jvm().await?; let true_value: ClassInstanceRef = jvm.new_class("java/lang/Boolean", "(Z)V", (true,)).await?.into(); - assert!(jvm.invoke_virtual::<_, bool>(&true_value, "booleanValue", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&true_value, "hashCode", "()I", ()).await?, 1231); + assert!( + jvm.invoke_virtual::<_, bool>(&true_value, "java/lang/Boolean", "booleanValue", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&true_value, "java/lang/Boolean", "hashCode", "()I", ()) + .await?, + 1231 + ); - let text: ClassInstanceRef = jvm.invoke_virtual(&true_value, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&true_value, "java/lang/Boolean", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "true"); let mixed_case = JavaLangString::from_rust_string(&jvm, "TrUe").await?; let parsed: ClassInstanceRef = jvm .invoke_static("java/lang/Boolean", "valueOf", "(Ljava/lang/String;)Ljava/lang/Boolean;", (mixed_case,)) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&parsed, "booleanValue", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&parsed, "java/lang/Boolean", "booleanValue", "()Z", ()) + .await? + ); let padded = JavaLangString::from_rust_string(&jvm, " true").await?; let parsed: ClassInstanceRef = jvm .invoke_static("java/lang/Boolean", "valueOf", "(Ljava/lang/String;)Ljava/lang/Boolean;", (padded,)) .await?; - assert!(!jvm.invoke_virtual::<_, bool>(&parsed, "booleanValue", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&parsed, "java/lang/Boolean", "booleanValue", "()Z", ()) + .await? + ); let null_string: ClassInstanceRef = None.into(); let parsed: ClassInstanceRef = jvm @@ -35,36 +50,57 @@ async fn test_boolean_string_constants_and_type() -> Result<()> { (null_string.clone(),), ) .await?; - assert!(!jvm.invoke_virtual::<_, bool>(&parsed, "booleanValue", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&parsed, "java/lang/Boolean", "booleanValue", "()Z", ()) + .await? + ); let from_null: ClassInstanceRef = jvm.new_class("java/lang/Boolean", "(Ljava/lang/String;)V", (null_string,)).await?.into(); - assert!(!jvm.invoke_virtual::<_, bool>(&from_null, "booleanValue", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&from_null, "java/lang/Boolean", "booleanValue", "()Z", ()) + .await? + ); let true_constant: ClassInstanceRef = jvm.get_static_field("java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;").await?; let false_constant: ClassInstanceRef = jvm.get_static_field("java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;").await?; - assert!(jvm.invoke_virtual::<_, bool>(&true_constant, "booleanValue", "()Z", ()).await?); - assert!(!jvm.invoke_virtual::<_, bool>(&false_constant, "booleanValue", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&false_constant, "hashCode", "()I", ()).await?, 1237); assert!( - jvm.invoke_virtual::<_, bool>(&true_constant, "equals", "(Ljava/lang/Object;)Z", (true_value,)) + jvm.invoke_virtual::<_, bool>(&true_constant, "java/lang/Boolean", "booleanValue", "()Z", ()) + .await? + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&false_constant, "java/lang/Boolean", "booleanValue", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&false_constant, "java/lang/Boolean", "hashCode", "()I", ()) + .await?, + 1237 + ); + assert!( + jvm.invoke_virtual::<_, bool>(&true_constant, "java/lang/Boolean", "equals", "(Ljava/lang/Object;)Z", (true_value,)) .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&false_constant, "equals", "(Ljava/lang/Object;)Z", (None,)) + !jvm.invoke_virtual::<_, bool>(&false_constant, "java/lang/Boolean", "equals", "(Ljava/lang/Object;)Z", (None,)) .await? ); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&false_constant, "equals", "(Ljava/lang/Object;)Z", (object,)) + !jvm.invoke_virtual::<_, bool>(&false_constant, "java/lang/Boolean", "equals", "(Ljava/lang/Object;)Z", (object,)) .await? ); assert!(!jvm.is_instance(&**true_constant, "java/lang/Comparable")); assert!(jvm.is_instance(&**true_constant, "java/io/Serializable")); let typ = jvm.get_static_field("java/lang/Boolean", "TYPE", "Ljava/lang/Class;").await?; - let name: ClassInstanceRef = jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "boolean"); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); Ok(()) } @@ -121,12 +157,22 @@ async fn test_boolean_property_and_java_5_primitive_value_of() -> Result<()> { let left = jvm.new_class("java/lang/Boolean", "(Z)V", (false,)).await?; let right = jvm.new_class("java/lang/Boolean", "(Z)V", (true,)).await?; - let result: Result = jvm.invoke_virtual(&left, "compareTo", "(Ljava/lang/Boolean;)I", (right.clone(),)).await; + let result: Result = jvm + .invoke_virtual( + &left, + &left.class_definition().name(), + "compareTo", + "(Ljava/lang/Boolean;)I", + (right.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Boolean typed compareTo must remain outside the Java 1.2 API"); }; assert!(jvm.is_instance(&*exception, "java/lang/NoSuchMethodError")); - let result: Result = jvm.invoke_virtual(&left, "compareTo", "(Ljava/lang/Object;)I", (right,)).await; + let result: Result = jvm + .invoke_virtual(&left, &left.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (right,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Boolean raw compareTo must remain outside the Java 1.2 API"); }; diff --git a/java_runtime/tests/classes/java/lang/test_byte.rs b/java_runtime/tests/classes/java/lang/test_byte.rs index b49458bc..a2c838d4 100644 --- a/java_runtime/tests/classes/java/lang/test_byte.rs +++ b/java_runtime/tests/classes/java/lang/test_byte.rs @@ -7,30 +7,63 @@ use test_utils::test_jvm; async fn test_byte_api() -> Result<()> { let jvm = test_jvm().await?; let value = jvm.new_class("java/lang/Byte", "(B)V", (-2i8,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i8>(&value, "byteValue", "()B", ()).await?, -2); - assert_eq!(jvm.invoke_virtual::<_, i16>(&value, "shortValue", "()S", ()).await?, -2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?, -2); - assert_eq!(jvm.invoke_virtual::<_, i64>(&value, "longValue", "()J", ()).await?, -2); - assert_eq!(jvm.invoke_virtual::<_, f32>(&value, "floatValue", "()F", ()).await?, -2.0); - assert_eq!(jvm.invoke_virtual::<_, f64>(&value, "doubleValue", "()D", ()).await?, -2.0); - let text: jvm::ClassInstanceRef = - jvm.invoke_virtual(&value, "toString", "()Ljava/lang/String;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i8>(&value, &value.class_definition().name(), "byteValue", "()B", ()) + .await?, + -2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i16>(&value, &value.class_definition().name(), "shortValue", "()S", ()) + .await?, + -2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?, + -2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&value, &value.class_definition().name(), "longValue", "()J", ()) + .await?, + -2 + ); + assert_eq!( + jvm.invoke_virtual::<_, f32>(&value, &value.class_definition().name(), "floatValue", "()F", ()) + .await?, + -2.0 + ); + assert_eq!( + jvm.invoke_virtual::<_, f64>(&value, &value.class_definition().name(), "doubleValue", "()D", ()) + .await?, + -2.0 + ); + let text: jvm::ClassInstanceRef = jvm + .invoke_virtual(&value, &value.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "-2"); let min = jvm.get_static_field::("java/lang/Byte", "MIN_VALUE", "B").await?; let max = jvm.get_static_field::("java/lang/Byte", "MAX_VALUE", "B").await?; assert_eq!((min, max), (i8::MIN, i8::MAX)); let typ = jvm.get_static_field("java/lang/Byte", "TYPE", "Ljava/lang/Class;").await?; - let name: jvm::ClassInstanceRef = - jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let name: jvm::ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "byte"); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); let string = JavaLangString::from_rust_string(&jvm, "0x7f").await?; let decoded = jvm .invoke_static("java/lang/Byte", "decode", "(Ljava/lang/String;)Ljava/lang/Byte;", (string,)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i8>(&decoded, "byteValue", "()B", ()).await?, 127); + assert_eq!( + jvm.invoke_virtual::<_, i8>(&decoded, &decoded.class_definition().name(), "byteValue", "()B", ()) + .await?, + 127 + ); let invalid = JavaLangString::from_rust_string(&jvm, "128").await?; let result: Result> = jvm @@ -41,7 +74,9 @@ async fn test_byte_api() -> Result<()> { }; assert!(jvm.is_instance(&*exception, "java/lang/NumberFormatException")); - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Byte;)I", (None,)).await; + let result: Result = jvm + .invoke_virtual(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Byte;)I", (None,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Byte typed compare null must throw NPE"); }; @@ -74,22 +109,36 @@ async fn test_byte_api() -> Result<()> { let equal = jvm.new_class("java/lang/Byte", "(B)V", (-2i8,)).await?; assert!( - jvm.invoke_virtual::<_, bool>(&value, "equals", "(Ljava/lang/Object;)Z", (equal.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &value, + &value.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (equal.clone(),) + ) + .await? ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&value, "hashCode", "()I", ()).await?, -2); assert_eq!( - jvm.invoke_virtual::<_, i32>(&value, "compareTo", "(Ljava/lang/Object;)I", (equal,)) + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "hashCode", "()I", ()) + .await?, + -2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (equal,)) .await?, 0 ); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Object;)I", (object,)).await; + let result: Result = jvm + .invoke_virtual(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (object,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Byte raw compare must reject another type"); }; assert!(jvm.is_instance(&*exception, "java/lang/ClassCastException")); - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Object;)I", (None,)).await; + let result: Result = jvm + .invoke_virtual(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (None,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Byte raw compare null must throw NPE"); }; @@ -100,12 +149,20 @@ async fn test_byte_api() -> Result<()> { let decoded: ClassInstanceRef = jvm .invoke_static("java/lang/Byte", "decode", "(Ljava/lang/String;)Ljava/lang/Byte;", (text,)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i8>(&decoded, "byteValue", "()B", ()).await?, expected); + assert_eq!( + jvm.invoke_virtual::<_, i8>(&decoded, "java/lang/Byte", "byteValue", "()B", ()).await?, + expected + ); } let typ = jvm.get_static_field("java/lang/Byte", "TYPE", "Ljava/lang/Class;").await?; - let name: ClassInstanceRef = jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "byte"); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/lang/test_character.rs b/java_runtime/tests/classes/java/lang/test_character.rs index 15270af2..cc1884c1 100644 --- a/java_runtime/tests/classes/java/lang/test_character.rs +++ b/java_runtime/tests/classes/java/lang/test_character.rs @@ -8,10 +8,19 @@ async fn test_character_value_constants_and_type() -> Result<()> { let jvm = test_jvm().await?; let value: ClassInstanceRef = jvm.new_class("java/lang/Character", "(C)V", ('A' as JavaChar,)).await?.into(); - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&value, "charValue", "()C", ()).await?, 'A' as JavaChar); - assert_eq!(jvm.invoke_virtual::<_, i32>(&value, "hashCode", "()I", ()).await?, 'A' as i32); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&value, "java/lang/Character", "charValue", "()C", ()) + .await?, + 'A' as JavaChar + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&value, "java/lang/Character", "hashCode", "()I", ()).await?, + 'A' as i32 + ); - let text: ClassInstanceRef = jvm.invoke_virtual(&value, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&value, "java/lang/Character", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "A"); assert_eq!(jvm.get_static_field::("java/lang/Character", "MIN_VALUE", "C").await?, 0); @@ -53,16 +62,25 @@ async fn test_character_value_constants_and_type() -> Result<()> { } let typ = jvm.get_static_field("java/lang/Character", "TYPE", "Ljava/lang/Class;").await?; - let name: ClassInstanceRef = jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "char"); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); assert!(jvm.is_instance(&**value, "java/lang/Comparable")); assert!(jvm.is_instance(&**value, "java/io/Serializable")); let result: ClassInstanceRef = jvm .invoke_static("java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", ('A' as JavaChar,)) .await?; - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&result, "charValue", "()C", ()).await?, 'A' as JavaChar); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&result, "java/lang/Character", "charValue", "()C", ()) + .await?, + 'A' as JavaChar + ); Ok(()) } @@ -270,9 +288,19 @@ async fn test_character_surrogate_and_compare_errors() -> Result<()> { let surrogate = 0xd800 as JavaChar; let value: ClassInstanceRef = jvm.new_class("java/lang/Character", "(C)V", (surrogate,)).await?.into(); - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&value, "charValue", "()C", ()).await?, surrogate); - let text: ClassInstanceRef = jvm.invoke_virtual(&value, "toString", "()Ljava/lang/String;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&text, "charAt", "(I)C", (0,)).await?, surrogate); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&value, "java/lang/Character", "charValue", "()C", ()) + .await?, + surrogate + ); + let text: ClassInstanceRef = jvm + .invoke_virtual(&value, "java/lang/Character", "toString", "()Ljava/lang/String;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&text, "java/lang/String", "charAt", "(I)C", (0,)) + .await?, + surrogate + ); for method in [ "isLowerCase", @@ -319,19 +347,19 @@ async fn test_character_surrogate_and_compare_errors() -> Result<()> { let other: ClassInstanceRef = jvm.new_class("java/lang/Character", "(C)V", ('Z' as JavaChar,)).await?.into(); assert_eq!( - jvm.invoke_virtual::<_, i32>(&value, "compareTo", "(Ljava/lang/Character;)I", (other.clone(),)) + jvm.invoke_virtual::<_, i32>(&value, "java/lang/Character", "compareTo", "(Ljava/lang/Character;)I", (other.clone(),)) .await?, 1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&other, "compareTo", "(Ljava/lang/Object;)I", (value.clone(),)) + jvm.invoke_virtual::<_, i32>(&other, "java/lang/Character", "compareTo", "(Ljava/lang/Object;)I", (value.clone(),)) .await?, -1 ); let null_character: ClassInstanceRef = None.into(); let result: Result = jvm - .invoke_virtual(&value, "compareTo", "(Ljava/lang/Character;)I", (null_character,)) + .invoke_virtual(&value, "java/lang/Character", "compareTo", "(Ljava/lang/Character;)I", (null_character,)) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Character.compareTo(Character) must reject null"); @@ -339,7 +367,9 @@ async fn test_character_surrogate_and_compare_errors() -> Result<()> { assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); let null_object: ClassInstanceRef = None.into(); - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Object;)I", (null_object,)).await; + let result: Result = jvm + .invoke_virtual(&value, "java/lang/Character", "compareTo", "(Ljava/lang/Object;)I", (null_object,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Character.compareTo(Object) must reject null"); }; @@ -347,14 +377,16 @@ async fn test_character_surrogate_and_compare_errors() -> Result<()> { let wrong = jvm.new_class("java/lang/Object", "()V", ()).await?; let result: Result = jvm - .invoke_virtual(&value, "compareTo", "(Ljava/lang/Character;)I", (wrong.clone(),)) + .invoke_virtual(&value, "java/lang/Character", "compareTo", "(Ljava/lang/Character;)I", (wrong.clone(),)) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("typed Character.compareTo must reject a non-Character instance"); }; assert!(jvm.is_instance(&*exception, "java/lang/ClassCastException")); - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Object;)I", (wrong,)).await; + let result: Result = jvm + .invoke_virtual(&value, "java/lang/Character", "compareTo", "(Ljava/lang/Object;)I", (wrong,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("raw Character.compareTo must reject a non-Character instance"); }; diff --git a/java_runtime/tests/classes/java/lang/test_class.rs b/java_runtime/tests/classes/java/lang/test_class.rs index c1094f10..fdd7d4d9 100644 --- a/java_runtime/tests/classes/java/lang/test_class.rs +++ b/java_runtime/tests/classes/java/lang/test_class.rs @@ -41,38 +41,92 @@ async fn cls_01_to_04_descriptors_and_standard_class_metadata() -> Result<()> { let string_array = jvm.resolve_class("[Ljava/lang/String;").await?.java_class(); let string_matrix = jvm.resolve_class("[[Ljava/lang/String;").await?.java_class(); - let superclass: ClassInstanceRef = jvm.invoke_virtual(&string, "getSuperclass", "()Ljava/lang/Class;", ()).await?; + let superclass: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "getSuperclass", "()Ljava/lang/Class;", ()) + .await?; assert_eq!(superclass.identity(), object.identity()); for class in [&object, &primitive] { - let superclass: ClassInstanceRef = jvm.invoke_virtual(class, "getSuperclass", "()Ljava/lang/Class;", ()).await?; + let superclass: ClassInstanceRef = jvm + .invoke_virtual(class, &class.class_definition().name(), "getSuperclass", "()Ljava/lang/Class;", ()) + .await?; assert!(superclass.is_null()); } - let array_superclass: ClassInstanceRef = jvm.invoke_virtual(&string_array, "getSuperclass", "()Ljava/lang/Class;", ()).await?; + let array_superclass: ClassInstanceRef = jvm + .invoke_virtual( + &string_array, + &string_array.class_definition().name(), + "getSuperclass", + "()Ljava/lang/Class;", + (), + ) + .await?; assert_eq!(array_superclass.identity(), object.identity()); let primitive_component: ClassInstanceRef = jvm - .invoke_virtual(&primitive_array, "getComponentType", "()Ljava/lang/Class;", ()) + .invoke_virtual( + &primitive_array, + &primitive_array.class_definition().name(), + "getComponentType", + "()Ljava/lang/Class;", + (), + ) .await?; assert_eq!(primitive_component.identity(), primitive.identity()); - let string_component: ClassInstanceRef = jvm.invoke_virtual(&string_array, "getComponentType", "()Ljava/lang/Class;", ()).await?; + let string_component: ClassInstanceRef = jvm + .invoke_virtual( + &string_array, + &string_array.class_definition().name(), + "getComponentType", + "()Ljava/lang/Class;", + (), + ) + .await?; assert_eq!(string_component.identity(), string.identity()); - let matrix_component: ClassInstanceRef = jvm.invoke_virtual(&string_matrix, "getComponentType", "()Ljava/lang/Class;", ()).await?; + let matrix_component: ClassInstanceRef = jvm + .invoke_virtual( + &string_matrix, + &string_matrix.class_definition().name(), + "getComponentType", + "()Ljava/lang/Class;", + (), + ) + .await?; assert_eq!(matrix_component.identity(), string_array.identity()); - let non_array_component: ClassInstanceRef = jvm.invoke_virtual(&string, "getComponentType", "()Ljava/lang/Class;", ()).await?; + let non_array_component: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "getComponentType", "()Ljava/lang/Class;", ()) + .await?; assert!(non_array_component.is_null()); - let string_interfaces: ClassInstanceRef> = jvm.invoke_virtual(&string, "getInterfaces", "()[Ljava/lang/Class;", ()).await?; + let string_interfaces: ClassInstanceRef> = jvm + .invoke_virtual(&string, &string.class_definition().name(), "getInterfaces", "()[Ljava/lang/Class;", ()) + .await?; let string_interfaces: Vec> = jvm.load_array(&string_interfaces, 0, 2).await?; assert_eq!(string_interfaces[0].identity(), serializable.identity()); assert_eq!(string_interfaces[1].identity(), comparable.identity()); - let array_interfaces: ClassInstanceRef> = jvm.invoke_virtual(&string_array, "getInterfaces", "()[Ljava/lang/Class;", ()).await?; + let array_interfaces: ClassInstanceRef> = jvm + .invoke_virtual( + &string_array, + &string_array.class_definition().name(), + "getInterfaces", + "()[Ljava/lang/Class;", + (), + ) + .await?; let array_interfaces: Vec> = jvm.load_array(&array_interfaces, 0, 2).await?; assert_eq!(JavaLangClass::name(&jvm, &array_interfaces[0]).await?, "java/lang/Cloneable"); assert_eq!(JavaLangClass::name(&jvm, &array_interfaces[1]).await?, "java/io/Serializable"); for class in [object, string, primitive_array, string_array, string_matrix] { - let loader: ClassInstanceRef = jvm.invoke_virtual(&class, "getClassLoader", "()Ljava/lang/ClassLoader;", ()).await?; + let loader: ClassInstanceRef = jvm + .invoke_virtual( + &class, + &class.class_definition().name(), + "getClassLoader", + "()Ljava/lang/ClassLoader;", + (), + ) + .await?; assert!(loader.is_null()); } @@ -103,14 +157,26 @@ async fn test_is_assignable_from() -> Result<()> { let object_class = jvm.resolve_class("java/lang/Object").await?.java_class(); let result: bool = jvm - .invoke_virtual(&object_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (string_class.clone(),)) + .invoke_virtual( + &object_class, + &object_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (string_class.clone(),), + ) .await?; assert!(result); let thread_class = jvm.resolve_class("java/lang/Thread").await?.java_class(); let result: bool = jvm - .invoke_virtual(&string_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (thread_class,)) + .invoke_virtual( + &string_class, + &string_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (thread_class,), + ) .await?; assert!(!result); @@ -122,6 +188,7 @@ async fn test_is_assignable_from() -> Result<()> { assert!( jvm.invoke_virtual::<_, bool>( &object_array_class, + &object_array_class.class_definition().name(), "isAssignableFrom", "(Ljava/lang/Class;)Z", (string_array_class.clone(),), @@ -129,16 +196,29 @@ async fn test_is_assignable_from() -> Result<()> { .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&string_array_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (object_array_class,),) - .await? + !jvm.invoke_virtual::<_, bool>( + &string_array_class, + &string_array_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (object_array_class,), + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&object_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (string_array_class.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &object_class, + &object_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (string_array_class.clone(),), + ) + .await? ); assert!( jvm.invoke_virtual::<_, bool>( &cloneable_class, + &cloneable_class.class_definition().name(), "isAssignableFrom", "(Ljava/lang/Class;)Z", (string_array_class.clone(),), @@ -146,8 +226,14 @@ async fn test_is_assignable_from() -> Result<()> { .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&serializable_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (string_array_class,),) - .await? + jvm.invoke_virtual::<_, bool>( + &serializable_class, + &serializable_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (string_array_class,), + ) + .await? ); Ok(()) @@ -185,10 +271,14 @@ async fn test_primitive_class_api() -> Result<()> { let primitive_name = JavaLangClass::name(&jvm, &primitive).await?; assert_eq!(primitive_name, name); - let virtual_name: ClassInstanceRef = jvm.invoke_virtual(&primitive, "getName", "()Ljava/lang/String;", ()).await?; + let virtual_name: ClassInstanceRef = jvm + .invoke_virtual(&primitive, &primitive.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &virtual_name).await?, name); - let is_primitive: bool = jvm.invoke_virtual(&primitive, "isPrimitive", "()Z", ()).await?; + let is_primitive: bool = jvm + .invoke_virtual(&primitive, &primitive.class_definition().name(), "isPrimitive", "()Z", ()) + .await?; assert!(is_primitive); let class_name = JavaLangString::from_rust_string(&jvm, name).await?; @@ -207,27 +297,57 @@ async fn test_primitive_class_api() -> Result<()> { let other_primitive = JavaLangClass::from_rust_primitive(&jvm, "long").await?; let result: bool = jvm - .invoke_virtual(&primitive, "isAssignableFrom", "(Ljava/lang/Class;)Z", (primitive.clone(),)) + .invoke_virtual( + &primitive, + &primitive.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (primitive.clone(),), + ) .await?; assert!(result); let result: bool = jvm - .invoke_virtual(&primitive, "isAssignableFrom", "(Ljava/lang/Class;)Z", (other_primitive,)) + .invoke_virtual( + &primitive, + &primitive.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (other_primitive,), + ) .await?; assert!(!result); let result: bool = jvm - .invoke_virtual(&primitive, "isAssignableFrom", "(Ljava/lang/Class;)Z", (string_class.clone(),)) + .invoke_virtual( + &primitive, + &primitive.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (string_class.clone(),), + ) .await?; assert!(!result); let result: bool = jvm - .invoke_virtual(&object_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (primitive,)) + .invoke_virtual( + &object_class, + &object_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (primitive,), + ) .await?; assert!(!result); let result: Result = jvm - .invoke_virtual(&object_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (None,)) + .invoke_virtual( + &object_class, + &object_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (None,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Class.isAssignableFrom(null) must throw NullPointerException"); @@ -252,9 +372,14 @@ async fn test_wrapper_type_fields_survive_gc() -> Result<()> { ("java/lang/Double", "double"), ] { let typ = jvm.get_static_field(wrapper, "TYPE", "Ljava/lang/Class;").await?; - let name: ClassInstanceRef = jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, primitive_name); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); } let _: () = jvm.invoke_static("java/lang/System", "gc", "()V", ()).await?; @@ -270,7 +395,10 @@ async fn test_wrapper_type_fields_survive_gc() -> Result<()> { "java/lang/Double", ] { let typ = jvm.get_static_field(wrapper, "TYPE", "Ljava/lang/Class;").await?; - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); } Ok(()) @@ -284,35 +412,86 @@ async fn test_cldc_class_queries_and_new_instance() -> Result<()> { let runnable_class = jvm.resolve_class("java/lang/Runnable").await?.java_class(); let array_class = jvm.resolve_class("[Ljava/lang/String;").await?.java_class(); - assert!(!jvm.invoke_virtual::<_, bool>(&string_class, "isArray", "()Z", ()).await?); - assert!(jvm.invoke_virtual::<_, bool>(&array_class, "isArray", "()Z", ()).await?); - assert!(jvm.invoke_virtual::<_, bool>(&runnable_class, "isInterface", "()Z", ()).await?); - - let value = JavaLangString::from_rust_string(&jvm, "value").await?; assert!( - jvm.invoke_virtual::<_, bool>(&string_class, "isInstance", "(Ljava/lang/Object;)Z", (value,)) + !jvm.invoke_virtual::<_, bool>(&string_class, &string_class.class_definition().name(), "isArray", "()Z", ()) .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&string_class, "isInstance", "(Ljava/lang/Object;)Z", (None,)) + jvm.invoke_virtual::<_, bool>(&array_class, &array_class.class_definition().name(), "isArray", "()Z", ()) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&runnable_class, &runnable_class.class_definition().name(), "isInterface", "()Z", ()) .await? ); + let value = JavaLangString::from_rust_string(&jvm, "value").await?; + assert!( + jvm.invoke_virtual::<_, bool>( + &string_class, + &string_class.class_definition().name(), + "isInstance", + "(Ljava/lang/Object;)Z", + (value,) + ) + .await? + ); + assert!( + !jvm.invoke_virtual::<_, bool>( + &string_class, + &string_class.class_definition().name(), + "isInstance", + "(Ljava/lang/Object;)Z", + (None,) + ) + .await? + ); + let object_class = jvm.resolve_class("java/lang/Object").await?.java_class(); - let instance: ClassInstanceRef = - jvm.invoke_virtual(&object_class, "newInstance", "()Ljava/lang/Object;", ()).await?; + let instance: ClassInstanceRef = jvm + .invoke_virtual( + &object_class, + &object_class.class_definition().name(), + "newInstance", + "()Ljava/lang/Object;", + (), + ) + .await?; assert!(jvm.is_instance(&**instance, "java/lang/Object")); - let result: Result> = - jvm.invoke_virtual(&runnable_class, "newInstance", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual( + &runnable_class, + &runnable_class.class_definition().name(), + "newInstance", + "()Ljava/lang/Object;", + (), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("interface instantiation must throw InstantiationException"); }; assert!(jvm.is_instance(&*exception, "java/lang/InstantiationException")); - let text: ClassInstanceRef = jvm.invoke_virtual(&string_class, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual( + &string_class, + &string_class.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "class java.lang.String"); - let text: ClassInstanceRef = jvm.invoke_virtual(&runnable_class, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual( + &runnable_class, + &runnable_class.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "interface java.lang.Runnable"); Ok(()) @@ -325,14 +504,26 @@ async fn test_base_class_loader_delegates_to_bootstrap_and_find_class_throws() - let name = JavaLangString::from_rust_string(&jvm, "java/util/Random").await?; let class: ClassInstanceRef = jvm - .invoke_virtual(&loader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", (name,)) + .invoke_virtual( + &loader, + "java/lang/ClassLoader", + "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (name,), + ) .await?; assert!(!class.is_null()); let name = JavaLangString::from_rust_string(&jvm, "missing.Type").await?; let result: Result> = jvm - .invoke_virtual(&loader, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;", (name,)) + .invoke_virtual( + &loader, + "java/lang/ClassLoader", + "findClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (name,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("ClassLoader.findClass must throw ClassNotFoundException"); @@ -366,8 +557,12 @@ async fn test_system_class_loader_uses_rustjar_parent() -> Result<()> { let urls: ClassInstanceRef> = jvm.get_field(&system_class_loader, "urls", "[Ljava/net/URL;").await?; assert_eq!(jvm.array_length(&urls).await?, 2); let urls: Vec> = jvm.load_array(&urls, 0, 2).await?; - let rustjar_file: ClassInstanceRef = jvm.invoke_virtual(&urls[0], "getFile", "()Ljava/lang/String;", ()).await?; - let classes_file: ClassInstanceRef = jvm.invoke_virtual(&urls[1], "getFile", "()Ljava/lang/String;", ()).await?; + let rustjar_file: ClassInstanceRef = jvm + .invoke_virtual(&urls[0], &urls[0].class_definition().name(), "getFile", "()Ljava/lang/String;", ()) + .await?; + let classes_file: ClassInstanceRef = jvm + .invoke_virtual(&urls[1], &urls[1].class_definition().name(), "getFile", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &rustjar_file).await?, "external.rustjar"); assert_eq!(JavaLangString::to_rust_string(&jvm, &classes_file).await?, "classes"); @@ -407,6 +602,7 @@ async fn test_define_class_translates_parser_errors_to_java_errors() -> Result<( let result: Result> = jvm .invoke_virtual( &loader, + "java/lang/ClassLoader", "defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;", (name.clone(), bytes, 0, length), @@ -439,6 +635,7 @@ async fn test_define_class_validates_the_byte_range() -> Result<()> { let result: Result> = jvm .invoke_virtual( &loader, + "java/lang/ClassLoader", "defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;", (name.clone(), bytes, offset, length), diff --git a/java_runtime/tests/classes/java/lang/test_cldc11_exceptions.rs b/java_runtime/tests/classes/java/lang/test_cldc11_exceptions.rs index f1d38224..08ee8724 100644 --- a/java_runtime/tests/classes/java/lang/test_cldc11_exceptions.rs +++ b/java_runtime/tests/classes/java/lang/test_cldc11_exceptions.rs @@ -140,7 +140,9 @@ async fn test_runtime_api_exception_and_error_message_constructors() -> Result<( ] { let message = JavaLangString::from_rust_string(&jvm, class_name).await?; let instance = jvm.new_class(class_name, "(Ljava/lang/String;)V", (message,)).await?; - let message: ClassInstanceRef = jvm.invoke_virtual(&instance, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual(&instance, &instance.class_definition().name(), "getMessage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, class_name); } diff --git a/java_runtime/tests/classes/java/lang/test_double.rs b/java_runtime/tests/classes/java/lang/test_double.rs index cfe270c9..2916fa22 100644 --- a/java_runtime/tests/classes/java/lang/test_double.rs +++ b/java_runtime/tests/classes/java/lang/test_double.rs @@ -8,16 +8,44 @@ async fn test_double_constructors_and_number_conversions() -> Result<()> { let jvm = test_jvm().await?; let value = jvm.new_class("java/lang/Double", "(D)V", (65_537.75f64,)).await?; - assert_eq!(jvm.invoke_virtual::<_, f64>(&value, "doubleValue", "()D", ()).await?, 65_537.75); - assert_eq!(jvm.invoke_virtual::<_, f32>(&value, "floatValue", "()F", ()).await?, 65_537.75f32); - assert_eq!(jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?, 65_537); - assert_eq!(jvm.invoke_virtual::<_, i64>(&value, "longValue", "()J", ()).await?, 65_537); - assert_eq!(jvm.invoke_virtual::<_, i8>(&value, "byteValue", "()B", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i16>(&value, "shortValue", "()S", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, f64>(&value, &value.class_definition().name(), "doubleValue", "()D", ()) + .await?, + 65_537.75 + ); + assert_eq!( + jvm.invoke_virtual::<_, f32>(&value, &value.class_definition().name(), "floatValue", "()F", ()) + .await?, + 65_537.75f32 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?, + 65_537 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&value, &value.class_definition().name(), "longValue", "()J", ()) + .await?, + 65_537 + ); + assert_eq!( + jvm.invoke_virtual::<_, i8>(&value, &value.class_definition().name(), "byteValue", "()B", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i16>(&value, &value.class_definition().name(), "shortValue", "()S", ()) + .await?, + 1 + ); let text = JavaLangString::from_rust_string(&jvm, "-3.5").await?; let from_string = jvm.new_class("java/lang/Double", "(Ljava/lang/String;)V", (text,)).await?; - assert_eq!(jvm.invoke_virtual::<_, f64>(&from_string, "doubleValue", "()D", ()).await?, -3.5); + assert_eq!( + jvm.invoke_virtual::<_, f64>(&from_string, &from_string.class_definition().name(), "doubleValue", "()D", ()) + .await?, + -3.5 + ); Ok(()) } @@ -51,7 +79,7 @@ async fn test_double_parse_value_of_and_format() -> Result<()> { let nan: ClassInstanceRef = jvm .invoke_static("java/lang/Double", "valueOf", "(Ljava/lang/String;)Ljava/lang/Double;", (nan,)) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&nan, "isNaN", "()Z", ()).await?); + assert!(jvm.invoke_virtual::<_, bool>(&nan, "java/lang/Double", "isNaN", "()Z", ()).await?); for (value, expected) in [(12.0f64, "12.0"), (-0.0, "-0.0"), (10_000_000.0, "1.0E7"), (0.000_125, "1.25E-4")] { let text: ClassInstanceRef = jvm @@ -137,12 +165,22 @@ async fn test_double_bits_equality_hash_and_comparison() -> Result<()> { let nan_a = jvm.new_class("java/lang/Double", "(D)V", (payload_nan_a,)).await?; let nan_b = jvm.new_class("java/lang/Double", "(D)V", (payload_nan_b,)).await?; assert!( - jvm.invoke_virtual::<_, bool>(&nan_a, "equals", "(Ljava/lang/Object;)Z", (nan_b.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &nan_a, + &nan_a.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (nan_b.clone(),) + ) + .await? ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&nan_a, "hashCode", "()I", ()).await?, 0x7ff8_0000); assert_eq!( - jvm.invoke_virtual::<_, i32>(&nan_a, "compareTo", "(Ljava/lang/Double;)I", (nan_b,)) + jvm.invoke_virtual::<_, i32>(&nan_a, &nan_a.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0x7ff8_0000 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&nan_a, &nan_a.class_definition().name(), "compareTo", "(Ljava/lang/Double;)I", (nan_b,)) .await?, 0 ); @@ -150,47 +188,105 @@ async fn test_double_bits_equality_hash_and_comparison() -> Result<()> { let negative_zero = jvm.new_class("java/lang/Double", "(D)V", (-0.0f64,)).await?; let positive_zero = jvm.new_class("java/lang/Double", "(D)V", (0.0f64,)).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&negative_zero, "equals", "(Ljava/lang/Object;)Z", (positive_zero.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &negative_zero, + &negative_zero.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (positive_zero.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&negative_zero, "compareTo", "(Ljava/lang/Double;)I", (positive_zero.clone(),),) - .await?, + jvm.invoke_virtual::<_, i32>( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Double;)I", + (positive_zero.clone(),), + ) + .await?, -1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&negative_zero, "compareTo", "(Ljava/lang/Object;)I", (positive_zero,)) - .await?, + jvm.invoke_virtual::<_, i32>( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (positive_zero,) + ) + .await?, -1 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&negative_zero, "hashCode", "()I", ()).await?, i32::MIN); assert_eq!( - jvm.invoke_virtual::<_, i32>(&jvm.new_class("java/lang/Double", "(D)V", (0.0f64,)).await?, "hashCode", "()I", (),) + jvm.invoke_virtual::<_, i32>(&negative_zero, &negative_zero.class_definition().name(), "hashCode", "()I", ()) .await?, + i32::MIN + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &jvm.new_class("java/lang/Double", "(D)V", (0.0f64,)).await?, + &jvm.new_class("java/lang/Double", "(D)V", (0.0f64,)).await?.class_definition().name(), + "hashCode", + "()I", + (), + ) + .await?, 0 ); let infinity = jvm.new_class("java/lang/Double", "(D)V", (f64::INFINITY,)).await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&nan_a, "compareTo", "(Ljava/lang/Double;)I", (infinity,)) - .await?, + jvm.invoke_virtual::<_, i32>( + &nan_a, + &nan_a.class_definition().name(), + "compareTo", + "(Ljava/lang/Double;)I", + (infinity,) + ) + .await?, 1 ); - let typed_null: Result = jvm.invoke_virtual(&negative_zero, "compareTo", "(Ljava/lang/Double;)I", (None,)).await; + let typed_null: Result = jvm + .invoke_virtual( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Double;)I", + (None,), + ) + .await; let Err(JavaError::JavaException(exception)) = typed_null else { panic!("Double typed compare null must throw NPE"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let raw_null: Result = jvm.invoke_virtual(&negative_zero, "compareTo", "(Ljava/lang/Object;)I", (None,)).await; + let raw_null: Result = jvm + .invoke_virtual( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (None,), + ) + .await; let Err(JavaError::JavaException(exception)) = raw_null else { panic!("Double raw compare null must throw NPE"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let wrong_type: Result = jvm.invoke_virtual(&negative_zero, "compareTo", "(Ljava/lang/Object;)I", (object,)).await; + let wrong_type: Result = jvm + .invoke_virtual( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (object,), + ) + .await; let Err(JavaError::JavaException(exception)) = wrong_type else { panic!("Double raw compare wrong type must throw CCE"); }; @@ -202,13 +298,30 @@ async fn test_double_bits_equality_hash_and_comparison() -> Result<()> { (f64::NEG_INFINITY, i32::MIN, i64::MIN), ] { let wrapper = jvm.new_class("java/lang/Double", "(D)V", (value,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&wrapper, "intValue", "()I", ()).await?, int_value); - assert_eq!(jvm.invoke_virtual::<_, i64>(&wrapper, "longValue", "()J", ()).await?, long_value); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&wrapper, &wrapper.class_definition().name(), "intValue", "()I", ()) + .await?, + int_value + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&wrapper, &wrapper.class_definition().name(), "longValue", "()J", ()) + .await?, + long_value + ); } let maximum = jvm.new_class("java/lang/Double", "(D)V", (f64::MAX,)).await?; - assert!(jvm.invoke_virtual::<_, f32>(&maximum, "floatValue", "()F", ()).await?.is_infinite()); + assert!( + jvm.invoke_virtual::<_, f32>(&maximum, &maximum.class_definition().name(), "floatValue", "()F", ()) + .await? + .is_infinite() + ); let minimum = jvm.new_class("java/lang/Double", "(D)V", (f64::from_bits(1),)).await?; - assert_eq!(jvm.invoke_virtual::<_, f32>(&minimum, "floatValue", "()F", ()).await?.to_bits(), 0); + assert_eq!( + jvm.invoke_virtual::<_, f32>(&minimum, &minimum.class_definition().name(), "floatValue", "()F", ()) + .await? + .to_bits(), + 0 + ); Ok(()) } @@ -235,9 +348,14 @@ async fn test_double_constants_type_and_predicates() -> Result<()> { ); let typ = jvm.get_static_field("java/lang/Double", "TYPE", "Ljava/lang/Class;").await?; - let name: ClassInstanceRef = jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "double"); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/lang/test_float.rs b/java_runtime/tests/classes/java/lang/test_float.rs index 1d1ef3f7..ffc01c04 100644 --- a/java_runtime/tests/classes/java/lang/test_float.rs +++ b/java_runtime/tests/classes/java/lang/test_float.rs @@ -8,16 +8,44 @@ async fn test_float_constructors_and_number_conversions() -> Result<()> { let jvm = test_jvm().await?; let value = jvm.new_class("java/lang/Float", "(D)V", (130.75f64,)).await?; - assert_eq!(jvm.invoke_virtual::<_, f32>(&value, "floatValue", "()F", ()).await?, 130.75); - assert_eq!(jvm.invoke_virtual::<_, f64>(&value, "doubleValue", "()D", ()).await?, 130.75); - assert_eq!(jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?, 130); - assert_eq!(jvm.invoke_virtual::<_, i64>(&value, "longValue", "()J", ()).await?, 130); - assert_eq!(jvm.invoke_virtual::<_, i8>(&value, "byteValue", "()B", ()).await?, -126); - assert_eq!(jvm.invoke_virtual::<_, i16>(&value, "shortValue", "()S", ()).await?, 130); + assert_eq!( + jvm.invoke_virtual::<_, f32>(&value, &value.class_definition().name(), "floatValue", "()F", ()) + .await?, + 130.75 + ); + assert_eq!( + jvm.invoke_virtual::<_, f64>(&value, &value.class_definition().name(), "doubleValue", "()D", ()) + .await?, + 130.75 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?, + 130 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&value, &value.class_definition().name(), "longValue", "()J", ()) + .await?, + 130 + ); + assert_eq!( + jvm.invoke_virtual::<_, i8>(&value, &value.class_definition().name(), "byteValue", "()B", ()) + .await?, + -126 + ); + assert_eq!( + jvm.invoke_virtual::<_, i16>(&value, &value.class_definition().name(), "shortValue", "()S", ()) + .await?, + 130 + ); let text = JavaLangString::from_rust_string(&jvm, "-3.5").await?; let from_string = jvm.new_class("java/lang/Float", "(Ljava/lang/String;)V", (text,)).await?; - assert_eq!(jvm.invoke_virtual::<_, f32>(&from_string, "floatValue", "()F", ()).await?, -3.5); + assert_eq!( + jvm.invoke_virtual::<_, f32>(&from_string, &from_string.class_definition().name(), "floatValue", "()F", ()) + .await?, + -3.5 + ); Ok(()) } @@ -51,7 +79,7 @@ async fn test_float_parse_value_of_and_format() -> Result<()> { let nan: ClassInstanceRef = jvm .invoke_static("java/lang/Float", "valueOf", "(Ljava/lang/String;)Ljava/lang/Float;", (nan,)) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&nan, "isNaN", "()Z", ()).await?); + assert!(jvm.invoke_virtual::<_, bool>(&nan, "java/lang/Float", "isNaN", "()Z", ()).await?); for (value, expected) in [(12.0f32, "12.0"), (-0.0, "-0.0"), (10_000_000.0, "1.0E7"), (0.000_125, "1.25E-4")] { let text: ClassInstanceRef = jvm @@ -131,12 +159,22 @@ async fn test_float_bits_equality_hash_and_comparison() -> Result<()> { let nan_a = jvm.new_class("java/lang/Float", "(F)V", (payload_nan_a,)).await?; let nan_b = jvm.new_class("java/lang/Float", "(F)V", (payload_nan_b,)).await?; assert!( - jvm.invoke_virtual::<_, bool>(&nan_a, "equals", "(Ljava/lang/Object;)Z", (nan_b.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &nan_a, + &nan_a.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (nan_b.clone(),) + ) + .await? ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&nan_a, "hashCode", "()I", ()).await?, 0x7fc0_0000); assert_eq!( - jvm.invoke_virtual::<_, i32>(&nan_a, "compareTo", "(Ljava/lang/Float;)I", (nan_b,)) + jvm.invoke_virtual::<_, i32>(&nan_a, &nan_a.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0x7fc0_0000 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&nan_a, &nan_a.class_definition().name(), "compareTo", "(Ljava/lang/Float;)I", (nan_b,)) .await?, 0 ); @@ -144,47 +182,99 @@ async fn test_float_bits_equality_hash_and_comparison() -> Result<()> { let negative_zero = jvm.new_class("java/lang/Float", "(F)V", (-0.0f32,)).await?; let positive_zero = jvm.new_class("java/lang/Float", "(F)V", (0.0f32,)).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&negative_zero, "equals", "(Ljava/lang/Object;)Z", (positive_zero.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &negative_zero, + &negative_zero.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (positive_zero.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&negative_zero, "compareTo", "(Ljava/lang/Float;)I", (positive_zero.clone(),),) - .await?, + jvm.invoke_virtual::<_, i32>( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Float;)I", + (positive_zero.clone(),), + ) + .await?, -1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&negative_zero, "compareTo", "(Ljava/lang/Object;)I", (positive_zero,)) - .await?, + jvm.invoke_virtual::<_, i32>( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (positive_zero,) + ) + .await?, -1 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&negative_zero, "hashCode", "()I", ()).await?, i32::MIN); assert_eq!( - jvm.invoke_virtual::<_, i32>(&jvm.new_class("java/lang/Float", "(F)V", (0.0f32,)).await?, "hashCode", "()I", (),) + jvm.invoke_virtual::<_, i32>(&negative_zero, &negative_zero.class_definition().name(), "hashCode", "()I", ()) .await?, + i32::MIN + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &jvm.new_class("java/lang/Float", "(F)V", (0.0f32,)).await?, + &jvm.new_class("java/lang/Float", "(F)V", (0.0f32,)).await?.class_definition().name(), + "hashCode", + "()I", + (), + ) + .await?, 0 ); let infinity = jvm.new_class("java/lang/Float", "(F)V", (f32::INFINITY,)).await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&nan_a, "compareTo", "(Ljava/lang/Float;)I", (infinity,)) + jvm.invoke_virtual::<_, i32>(&nan_a, &nan_a.class_definition().name(), "compareTo", "(Ljava/lang/Float;)I", (infinity,)) .await?, 1 ); - let typed_null: Result = jvm.invoke_virtual(&negative_zero, "compareTo", "(Ljava/lang/Float;)I", (None,)).await; + let typed_null: Result = jvm + .invoke_virtual( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Float;)I", + (None,), + ) + .await; let Err(JavaError::JavaException(exception)) = typed_null else { panic!("Float typed compare null must throw NPE"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let raw_null: Result = jvm.invoke_virtual(&negative_zero, "compareTo", "(Ljava/lang/Object;)I", (None,)).await; + let raw_null: Result = jvm + .invoke_virtual( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (None,), + ) + .await; let Err(JavaError::JavaException(exception)) = raw_null else { panic!("Float raw compare null must throw NPE"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let wrong_type: Result = jvm.invoke_virtual(&negative_zero, "compareTo", "(Ljava/lang/Object;)I", (object,)).await; + let wrong_type: Result = jvm + .invoke_virtual( + &negative_zero, + &negative_zero.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (object,), + ) + .await; let Err(JavaError::JavaException(exception)) = wrong_type else { panic!("Float raw compare wrong type must throw CCE"); }; @@ -196,8 +286,16 @@ async fn test_float_bits_equality_hash_and_comparison() -> Result<()> { (f32::NEG_INFINITY, i32::MIN, i64::MIN), ] { let wrapper = jvm.new_class("java/lang/Float", "(F)V", (value,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&wrapper, "intValue", "()I", ()).await?, int_value); - assert_eq!(jvm.invoke_virtual::<_, i64>(&wrapper, "longValue", "()J", ()).await?, long_value); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&wrapper, &wrapper.class_definition().name(), "intValue", "()I", ()) + .await?, + int_value + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&wrapper, &wrapper.class_definition().name(), "longValue", "()J", ()) + .await?, + long_value + ); } Ok(()) @@ -225,9 +323,14 @@ async fn test_float_constants_type_and_predicates() -> Result<()> { ); let typ = jvm.get_static_field("java/lang/Float", "TYPE", "Ljava/lang/Class;").await?; - let name: ClassInstanceRef = jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "float"); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/lang/test_integer.rs b/java_runtime/tests/classes/java/lang/test_integer.rs index fab0648d..9cb4c0bf 100644 --- a/java_runtime/tests/classes/java/lang/test_integer.rs +++ b/java_runtime/tests/classes/java/lang/test_integer.rs @@ -15,7 +15,10 @@ async fn test_parse_int() -> Result<()> { ); let boxed: ClassInstanceRef = jvm.invoke_static("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", (42,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&boxed, "intValue", "()I", ()).await?, 42); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&boxed, "java/lang/Integer", "intValue", "()I", ()).await?, + 42 + ); Ok(()) } @@ -73,7 +76,10 @@ async fn test_integer_strict_api() -> Result<()> { let decoded: ClassInstanceRef = jvm .invoke_static("java/lang/Integer", "decode", "(Ljava/lang/String;)Ljava/lang/Integer;", (decoded_name,)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&decoded, "intValue", "()I", ()).await?, i32::MIN); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&decoded, "java/lang/Integer", "intValue", "()I", ()).await?, + i32::MIN + ); for (method, expected) in [ ("toBinaryString", "11111111111111111111111111111111"), @@ -87,35 +93,63 @@ async fn test_integer_strict_api() -> Result<()> { let left = jvm.new_class("java/lang/Integer", "(I)V", (1,)).await?; let right = jvm.new_class("java/lang/Integer", "(I)V", (2,)).await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&left, "compareTo", "(Ljava/lang/Integer;)I", (right.clone(),)) - .await?, + jvm.invoke_virtual::<_, i32>( + &left, + &left.class_definition().name(), + "compareTo", + "(Ljava/lang/Integer;)I", + (right.clone(),) + ) + .await?, -1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&left, "compareTo", "(Ljava/lang/Object;)I", (right.clone(),)) - .await?, + jvm.invoke_virtual::<_, i32>( + &left, + &left.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (right.clone(),) + ) + .await?, -1 ); assert!( - !jvm.invoke_virtual::<_, bool>(&left, "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &left, + &left.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (right.clone(),) + ) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&left, &left.class_definition().name(), "hashCode", "()I", ()) + .await?, + 1 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&left, "hashCode", "()I", ()).await?, 1); - let typed_null_result: Result = jvm.invoke_virtual(&left, "compareTo", "(Ljava/lang/Integer;)I", (None,)).await; + let typed_null_result: Result = jvm + .invoke_virtual(&left, &left.class_definition().name(), "compareTo", "(Ljava/lang/Integer;)I", (None,)) + .await; let Err(JavaError::JavaException(exception)) = typed_null_result else { panic!("Integer typed compare null must throw NPE"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let null_result: Result = jvm.invoke_virtual(&left, "compareTo", "(Ljava/lang/Object;)I", (None,)).await; + let null_result: Result = jvm + .invoke_virtual(&left, &left.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (None,)) + .await; let Err(JavaError::JavaException(exception)) = null_result else { panic!("Integer raw compare null must throw NPE"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let wrong_result: Result = jvm.invoke_virtual(&left, "compareTo", "(Ljava/lang/Object;)I", (object,)).await; + let wrong_result: Result = jvm + .invoke_virtual(&left, &left.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (object,)) + .await; let Err(JavaError::JavaException(exception)) = wrong_result else { panic!("Integer raw compare wrong type must throw CCE"); }; @@ -125,12 +159,20 @@ async fn test_integer_strict_api() -> Result<()> { let max = jvm.get_static_field::("java/lang/Integer", "MAX_VALUE", "I").await?; assert_eq!((min, max), (i32::MIN, i32::MAX)); let typ = jvm.get_static_field("java/lang/Integer", "TYPE", "Ljava/lang/Class;").await?; - let name: ClassInstanceRef = jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let name: ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "int"); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); let _: () = jvm.invoke_static("java/lang/System", "gc", "()V", ()).await?; let typ = jvm.get_static_field("java/lang/Integer", "TYPE", "Ljava/lang/Class;").await?; - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); Ok(()) } @@ -177,7 +219,10 @@ async fn test_integer_rejects_invalid_forms_and_uses_property_defaults() -> Resu let decoded: ClassInstanceRef = jvm .invoke_static("java/lang/Integer", "decode", "(Ljava/lang/String;)Ljava/lang/Integer;", (text,)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&decoded, "intValue", "()I", ()).await?, expected); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&decoded, "java/lang/Integer", "intValue", "()I", ()).await?, + expected + ); } let key = JavaLangString::from_rust_string(&jvm, "rustjava.test.integer").await?; @@ -198,7 +243,11 @@ async fn test_integer_rejects_invalid_forms_and_uses_property_defaults() -> Resu (key.clone(),), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&property, "intValue", "()I", ()).await?, 42); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&property, "java/lang/Integer", "intValue", "()I", ()) + .await?, + 42 + ); let invalid = JavaLangString::from_rust_string(&jvm, "not-an-integer").await?; let _: ClassInstanceRef = jvm @@ -217,7 +266,11 @@ async fn test_integer_rejects_invalid_forms_and_uses_property_defaults() -> Resu (key.clone(), 17), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&property, "intValue", "()I", ()).await?, 17); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&property, "java/lang/Integer", "intValue", "()I", ()) + .await?, + 17 + ); let default = jvm.new_class("java/lang/Integer", "(I)V", (23,)).await?; let property: ClassInstanceRef = jvm @@ -228,7 +281,11 @@ async fn test_integer_rejects_invalid_forms_and_uses_property_defaults() -> Resu (key, default), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&property, "intValue", "()I", ()).await?, 23); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&property, "java/lang/Integer", "intValue", "()I", ()) + .await?, + 23 + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/lang/test_long.rs b/java_runtime/tests/classes/java/lang/test_long.rs index 02eb73e9..23d1eeff 100644 --- a/java_runtime/tests/classes/java/lang/test_long.rs +++ b/java_runtime/tests/classes/java/lang/test_long.rs @@ -7,12 +7,36 @@ use test_utils::test_jvm; async fn test_long_api() -> Result<()> { let jvm = test_jvm().await?; let value = jvm.new_class("java/lang/Long", "(J)V", (i64::MIN,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i8>(&value, "byteValue", "()B", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i16>(&value, "shortValue", "()S", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i64>(&value, "longValue", "()J", ()).await?, i64::MIN); - assert_eq!(jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, f32>(&value, "floatValue", "()F", ()).await?, i64::MIN as f32); - assert_eq!(jvm.invoke_virtual::<_, f64>(&value, "doubleValue", "()D", ()).await?, i64::MIN as f64); + assert_eq!( + jvm.invoke_virtual::<_, i8>(&value, &value.class_definition().name(), "byteValue", "()B", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i16>(&value, &value.class_definition().name(), "shortValue", "()S", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&value, &value.class_definition().name(), "longValue", "()J", ()) + .await?, + i64::MIN + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, f32>(&value, &value.class_definition().name(), "floatValue", "()F", ()) + .await?, + i64::MIN as f32 + ); + assert_eq!( + jvm.invoke_virtual::<_, f64>(&value, &value.class_definition().name(), "doubleValue", "()D", ()) + .await?, + i64::MIN as f64 + ); for (input, radix, expected) in [ ("7fffffffffffffff", 16, i64::MAX), @@ -39,7 +63,11 @@ async fn test_long_api() -> Result<()> { .invoke_static("java/lang/Long", "toHexString", "(J)Ljava/lang/String;", (-1i64,)) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &hex).await?, "ffffffffffffffff"); - assert_eq!(jvm.invoke_virtual::<_, i64>(&value, "longValue", "()J", ()).await?, -1); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&value, &value.class_definition().name(), "longValue", "()J", ()) + .await?, + -1 + ); let overflow = JavaLangString::from_rust_string(&jvm, "9223372036854775808").await?; let result: Result = jvm @@ -50,7 +78,9 @@ async fn test_long_api() -> Result<()> { }; assert!(jvm.is_instance(&*exception, "java/lang/NumberFormatException")); - let typed_null_result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Long;)I", (None,)).await; + let typed_null_result: Result = jvm + .invoke_virtual(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Long;)I", (None,)) + .await; let Err(JavaError::JavaException(exception)) = typed_null_result else { panic!("Long typed compare null must throw NPE"); }; @@ -78,7 +108,10 @@ async fn test_long_api() -> Result<()> { let property: ClassInstanceRef = jvm .invoke_static("java/lang/Long", "getLong", "(Ljava/lang/String;)Ljava/lang/Long;", (key.clone(),)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&property, "longValue", "()J", ()).await?, 63); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&property, "java/lang/Long", "longValue", "()J", ()).await?, + 63 + ); let invalid = JavaLangString::from_rust_string(&jvm, "invalid").await?; let _: ClassInstanceRef = jvm @@ -92,7 +125,10 @@ async fn test_long_api() -> Result<()> { let property: ClassInstanceRef = jvm .invoke_static("java/lang/Long", "getLong", "(Ljava/lang/String;J)Ljava/lang/Long;", (key, -9i64)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&property, "longValue", "()J", ()).await?, -9); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&property, "java/lang/Long", "longValue", "()J", ()).await?, + -9 + ); for (text, radix, expected) in [ ("-1000000000000000000000000000000000000000000000000000000000000000", 2, i64::MIN), @@ -124,7 +160,10 @@ async fn test_long_api() -> Result<()> { let decoded: ClassInstanceRef = jvm .invoke_static("java/lang/Long", "decode", "(Ljava/lang/String;)Ljava/lang/Long;", (text,)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&decoded, "longValue", "()J", ()).await?, expected); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&decoded, "java/lang/Long", "longValue", "()J", ()).await?, + expected + ); } for (method, expected) in [ ("toBinaryString", "1111111111111111111111111111111111111111111111111111111111111111"), @@ -137,22 +176,36 @@ async fn test_long_api() -> Result<()> { let equal = jvm.new_class("java/lang/Long", "(J)V", (-1i64,)).await?; assert!( - jvm.invoke_virtual::<_, bool>(&value, "equals", "(Ljava/lang/Object;)Z", (equal.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &value, + &value.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (equal.clone(),) + ) + .await? ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&value, "hashCode", "()I", ()).await?, 0); assert_eq!( - jvm.invoke_virtual::<_, i32>(&value, "compareTo", "(Ljava/lang/Object;)I", (equal,)) + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (equal,)) .await?, 0 ); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Object;)I", (object,)).await; + let result: Result = jvm + .invoke_virtual(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (object,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Long raw compare must reject another type"); }; assert!(jvm.is_instance(&*exception, "java/lang/ClassCastException")); - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Object;)I", (None,)).await; + let result: Result = jvm + .invoke_virtual(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (None,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Long raw compare null must throw NPE"); }; @@ -161,8 +214,13 @@ async fn test_long_api() -> Result<()> { assert_eq!(jvm.get_static_field::("java/lang/Long", "MIN_VALUE", "J").await?, i64::MIN); assert_eq!(jvm.get_static_field::("java/lang/Long", "MAX_VALUE", "J").await?, i64::MAX); let typ = jvm.get_static_field("java/lang/Long", "TYPE", "Ljava/lang/Class;").await?; - let type_name: ClassInstanceRef = jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let type_name: ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &type_name).await?, "long"); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/lang/test_number.rs b/java_runtime/tests/classes/java/lang/test_number.rs index 62f19932..e5fa3277 100644 --- a/java_runtime/tests/classes/java/lang/test_number.rs +++ b/java_runtime/tests/classes/java/lang/test_number.rs @@ -32,16 +32,34 @@ async fn test_number_is_abstract() -> Result<()> { let number_class = jvm.resolve_class("java/lang/Number").await?.java_class(); let serializable_class = jvm.resolve_class("java/io/Serializable").await?.java_class(); let is_serializable: bool = jvm - .invoke_virtual(&serializable_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (number_class.clone(),)) + .invoke_virtual( + &serializable_class, + &serializable_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (number_class.clone(),), + ) .await?; assert!(is_serializable); let comparable_class = jvm.resolve_class("java/lang/Comparable").await?.java_class(); let integer = jvm.new_class("java/lang/Integer", "(I)V", (257,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i8>(&integer, "byteValue", "()B", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i16>(&integer, "shortValue", "()S", ()).await?, 257); + assert_eq!( + jvm.invoke_virtual::<_, i8>(&integer, &integer.class_definition().name(), "byteValue", "()B", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i16>(&integer, &integer.class_definition().name(), "shortValue", "()S", ()) + .await?, + 257 + ); let negative = jvm.new_class("java/lang/Integer", "(I)V", (-129,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i8>(&negative, "byteValue", "()B", ()).await?, 127); + assert_eq!( + jvm.invoke_virtual::<_, i8>(&negative, &negative.class_definition().name(), "byteValue", "()B", ()) + .await?, + 127 + ); for class_name in [ "java/lang/Byte", @@ -53,15 +71,33 @@ async fn test_number_is_abstract() -> Result<()> { ] { let wrapper_class = jvm.resolve_class(class_name).await?.java_class(); let is_number: bool = jvm - .invoke_virtual(&number_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (wrapper_class.clone(),)) + .invoke_virtual( + &number_class, + &number_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (wrapper_class.clone(),), + ) .await?; assert!(is_number); let is_serializable: bool = jvm - .invoke_virtual(&serializable_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (wrapper_class.clone(),)) + .invoke_virtual( + &serializable_class, + &serializable_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (wrapper_class.clone(),), + ) .await?; assert!(is_serializable); let is_comparable: bool = jvm - .invoke_virtual(&comparable_class, "isAssignableFrom", "(Ljava/lang/Class;)Z", (wrapper_class,)) + .invoke_virtual( + &comparable_class, + &comparable_class.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (wrapper_class,), + ) .await?; assert!(is_comparable); } diff --git a/java_runtime/tests/classes/java/lang/test_object.rs b/java_runtime/tests/classes/java/lang/test_object.rs index 0ed60931..6b221641 100644 --- a/java_runtime/tests/classes/java/lang/test_object.rs +++ b/java_runtime/tests/classes/java/lang/test_object.rs @@ -55,7 +55,10 @@ async fn test_wait() -> Result<()> { self.runtime.sleep(Duration::from_millis(100)).await; self.notified.store(true, Ordering::Relaxed); self.jvm.monitor_enter(&self.target).await?; - let _: () = self.jvm.invoke_virtual(&self.target, "notify", "()V", ()).await?; + let _: () = self + .jvm + .invoke_virtual(&self.target, &self.target.class_definition().name(), "notify", "()V", ()) + .await?; self.jvm.monitor_exit(&self.target).await?; self.jvm.detach_thread()?; @@ -76,7 +79,7 @@ async fn test_wait() -> Result<()> { assert!(!notified.load(Ordering::Relaxed)); jvm.monitor_enter(&object).await?; - let _: () = jvm.invoke_virtual(&object, "wait", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&object, &object.class_definition().name(), "wait", "()V", ()).await?; jvm.monitor_exit(&object).await?; assert!(notified.load(Ordering::Relaxed)); @@ -89,7 +92,9 @@ async fn test_wait_timeout() -> Result<()> { let object = jvm.new_class("java/lang/Object", "()V", ()).await?; jvm.monitor_enter(&object).await?; - let _: () = jvm.invoke_virtual(&object, "wait", "(J)V", (100i64,)).await?; + let _: () = jvm + .invoke_virtual(&object, &object.class_definition().name(), "wait", "(J)V", (100i64,)) + .await?; jvm.monitor_exit(&object).await?; Ok(()) @@ -102,8 +107,10 @@ async fn test_wait_and_notify_require_monitor_ownership() -> Result<()> { let object = jvm.new_class("java/lang/Object", "()V", ()).await?; for result in [ - jvm.invoke_virtual::<_, ()>(&object, "notify", "()V", ()).await, - jvm.invoke_virtual::<_, ()>(&object, "wait", "(J)V", (1i64,)).await, + jvm.invoke_virtual::<_, ()>(&object, &object.class_definition().name(), "notify", "()V", ()) + .await, + jvm.invoke_virtual::<_, ()>(&object, &object.class_definition().name(), "wait", "(J)V", (1i64,)) + .await, ] { let Err(JavaError::JavaException(exception)) = result else { panic!("monitor ownership violation must throw IllegalMonitorStateException"); @@ -121,7 +128,9 @@ async fn test_clone_not_cloneable() -> Result<()> { let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let result: Result> = jvm.invoke_virtual(&object, "clone", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&object, &object.class_definition().name(), "clone", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(java_exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; @@ -150,7 +159,9 @@ async fn test_clone_creates_shallow_object_and_array_copies() -> Result<()> { jvm.put_field(&mut original, "value", "I", 7i32).await?; jvm.put_field(&mut original, "reference", "Ljava/lang/Object;", reference.clone()).await?; - let mut cloned: ClassInstanceRef = jvm.invoke_virtual(&original, "clone", "()Ljava/lang/Object;", ()).await?; + let mut cloned: ClassInstanceRef = jvm + .invoke_virtual(&original, &original.class_definition().name(), "clone", "()Ljava/lang/Object;", ()) + .await?; assert_ne!(original.identity(), cloned.identity()); assert_eq!(jvm.get_field::(&cloned, "value", "I").await?, 7); let cloned_reference = jvm @@ -163,7 +174,9 @@ async fn test_clone_creates_shallow_object_and_array_copies() -> Result<()> { let mut array = jvm.instantiate_array("I", 2).await?; jvm.store_array(&mut array, 0, [1i32, 2i32]).await?; - let mut cloned_array: ClassInstanceRef> = jvm.invoke_virtual(&array, "clone", "()Ljava/lang/Object;", ()).await?; + let mut cloned_array: ClassInstanceRef> = jvm + .invoke_virtual(&array, &array.class_definition().name(), "clone", "()Ljava/lang/Object;", ()) + .await?; assert_ne!(array.identity(), cloned_array.identity()); jvm.store_array(&mut cloned_array, 0, [9i32]).await?; assert_eq!(jvm.load_array::(&array, 0, 2).await?, [1, 2]); @@ -171,8 +184,15 @@ async fn test_clone_creates_shallow_object_and_array_copies() -> Result<()> { let mut reference_array = jvm.instantiate_array("Ljava/lang/Object;", 1).await?; jvm.store_array(&mut reference_array, 0, [reference.clone()]).await?; - let mut cloned_reference_array: ClassInstanceRef> = - jvm.invoke_virtual(&reference_array, "clone", "()Ljava/lang/Object;", ()).await?; + let mut cloned_reference_array: ClassInstanceRef> = jvm + .invoke_virtual( + &reference_array, + &reference_array.class_definition().name(), + "clone", + "()Ljava/lang/Object;", + (), + ) + .await?; let cloned_element = jvm.load_array::>(&cloned_reference_array, 0, 1).await?; assert_eq!(cloned_element[0].identity(), reference.identity()); let replacement: ClassInstanceRef = jvm.new_class("java/lang/Object", "()V", ()).await?.into(); @@ -190,8 +210,12 @@ async fn test_hash_code_is_stable_for_same_object() -> Result<()> { let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let first: i32 = jvm.invoke_virtual(&object, "hashCode", "()I", ()).await?; - let second: i32 = jvm.invoke_virtual(&object, "hashCode", "()I", ()).await?; + let first: i32 = jvm + .invoke_virtual(&object, &object.class_definition().name(), "hashCode", "()I", ()) + .await?; + let second: i32 = jvm + .invoke_virtual(&object, &object.class_definition().name(), "hashCode", "()I", ()) + .await?; assert_eq!(first, second); @@ -207,7 +231,9 @@ async fn test_hash_code_is_not_constant_across_objects() -> Result<()> { for _ in 0..32 { let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let hash: i32 = jvm.invoke_virtual(&object, "hashCode", "()I", ()).await?; + let hash: i32 = jvm + .invoke_virtual(&object, &object.class_definition().name(), "hashCode", "()I", ()) + .await?; hashes.insert(hash); } diff --git a/java_runtime/tests/classes/java/lang/test_short.rs b/java_runtime/tests/classes/java/lang/test_short.rs index 91be27a0..e1904582 100644 --- a/java_runtime/tests/classes/java/lang/test_short.rs +++ b/java_runtime/tests/classes/java/lang/test_short.rs @@ -7,12 +7,36 @@ use test_utils::test_jvm; async fn test_short_api() -> Result<()> { let jvm = test_jvm().await?; let value = jvm.new_class("java/lang/Short", "(S)V", (-129i16,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i8>(&value, "byteValue", "()B", ()).await?, 127); - assert_eq!(jvm.invoke_virtual::<_, i16>(&value, "shortValue", "()S", ()).await?, -129); - assert_eq!(jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?, -129); - assert_eq!(jvm.invoke_virtual::<_, i64>(&value, "longValue", "()J", ()).await?, -129); - assert_eq!(jvm.invoke_virtual::<_, f32>(&value, "floatValue", "()F", ()).await?, -129.0); - assert_eq!(jvm.invoke_virtual::<_, f64>(&value, "doubleValue", "()D", ()).await?, -129.0); + assert_eq!( + jvm.invoke_virtual::<_, i8>(&value, &value.class_definition().name(), "byteValue", "()B", ()) + .await?, + 127 + ); + assert_eq!( + jvm.invoke_virtual::<_, i16>(&value, &value.class_definition().name(), "shortValue", "()S", ()) + .await?, + -129 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?, + -129 + ); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&value, &value.class_definition().name(), "longValue", "()J", ()) + .await?, + -129 + ); + assert_eq!( + jvm.invoke_virtual::<_, f32>(&value, &value.class_definition().name(), "floatValue", "()F", ()) + .await?, + -129.0 + ); + assert_eq!( + jvm.invoke_virtual::<_, f64>(&value, &value.class_definition().name(), "doubleValue", "()D", ()) + .await?, + -129.0 + ); for (input, radix, expected) in [("7f", 16, 127i16), ("-100000", 2, -32i16)] { let string = JavaLangString::from_rust_string(&jvm, input).await?; @@ -29,7 +53,11 @@ async fn test_short_api() -> Result<()> { let decoded = jvm .invoke_static("java/lang/Short", "decode", "(Ljava/lang/String;)Ljava/lang/Short;", (name,)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i16>(&decoded, "shortValue", "()S", ()).await?, 63); + assert_eq!( + jvm.invoke_virtual::<_, i16>(&decoded, &decoded.class_definition().name(), "shortValue", "()S", ()) + .await?, + 63 + ); let null_result: Result = jvm.invoke_static("java/lang/Short", "parseShort", "(Ljava/lang/String;)S", (None,)).await; let Err(JavaError::JavaException(exception)) = null_result else { @@ -37,7 +65,9 @@ async fn test_short_api() -> Result<()> { }; assert!(jvm.is_instance(&*exception, "java/lang/NumberFormatException")); - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Short;)I", (None,)).await; + let result: Result = jvm + .invoke_virtual(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Short;)I", (None,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Short typed compare null must throw NPE"); }; @@ -70,22 +100,36 @@ async fn test_short_api() -> Result<()> { let equal = jvm.new_class("java/lang/Short", "(S)V", (-129i16,)).await?; assert!( - jvm.invoke_virtual::<_, bool>(&value, "equals", "(Ljava/lang/Object;)Z", (equal.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &value, + &value.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (equal.clone(),) + ) + .await? ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&value, "hashCode", "()I", ()).await?, -129); assert_eq!( - jvm.invoke_virtual::<_, i32>(&value, "compareTo", "(Ljava/lang/Object;)I", (equal,)) + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "hashCode", "()I", ()) + .await?, + -129 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (equal,)) .await?, 0 ); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Object;)I", (object,)).await; + let result: Result = jvm + .invoke_virtual(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (object,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Short raw compare must reject another type"); }; assert!(jvm.is_instance(&*exception, "java/lang/ClassCastException")); - let result: Result = jvm.invoke_virtual(&value, "compareTo", "(Ljava/lang/Object;)I", (None,)).await; + let result: Result = jvm + .invoke_virtual(&value, &value.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (None,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Short raw compare null must throw NPE"); }; @@ -96,12 +140,21 @@ async fn test_short_api() -> Result<()> { let decoded = jvm .invoke_static("java/lang/Short", "decode", "(Ljava/lang/String;)Ljava/lang/Short;", (text,)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i16>(&decoded, "shortValue", "()S", ()).await?, expected); + assert_eq!( + jvm.invoke_virtual::<_, i16>(&decoded, &decoded.class_definition().name(), "shortValue", "()S", ()) + .await?, + expected + ); } let typ = jvm.get_static_field("java/lang/Short", "TYPE", "Ljava/lang/Class;").await?; - let type_name: ClassInstanceRef = jvm.invoke_virtual(&typ, "getName", "()Ljava/lang/String;", ()).await?; + let type_name: ClassInstanceRef = jvm + .invoke_virtual(&typ, &typ.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &type_name).await?, "short"); - assert!(jvm.invoke_virtual::<_, bool>(&typ, "isPrimitive", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&typ, &typ.class_definition().name(), "isPrimitive", "()Z", ()) + .await? + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/lang/test_string.rs b/java_runtime/tests/classes/java/lang/test_string.rs index 43e77e25..3e2cb524 100644 --- a/java_runtime/tests/classes/java/lang/test_string.rs +++ b/java_runtime/tests/classes/java/lang/test_string.rs @@ -46,11 +46,29 @@ async fn string_implements_char_sequence_and_sub_sequence_uses_utf16_indices() - let jvm = test_jvm().await?; let string = JavaLangString::from_rust_string(&jvm, "a😀b").await?; - let subsequence: ClassInstanceRef = jvm.invoke_virtual(&string, "subSequence", "(II)Ljava/lang/CharSequence;", (1, 3)).await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&subsequence, "toString", "()Ljava/lang/String;", ()).await?; + let subsequence: ClassInstanceRef = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (1, 3), + ) + .await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&subsequence, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "😀"); - let result: Result> = jvm.invoke_virtual(&string, "subSequence", "(II)Ljava/lang/CharSequence;", (3, 2)).await; + let result: Result> = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "subSequence", + "(II)Ljava/lang/CharSequence;", + (3, 2), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("String.subSequence must preserve substring range validation"); }; @@ -94,7 +112,9 @@ async fn string_regex_methods_match_direct_pattern_and_matcher_results() -> Resu (regex.clone(), input), ) .await?; - let string_matches: bool = jvm.invoke_virtual(&value, "matches", "(Ljava/lang/String;)Z", (regex,)).await?; + let string_matches: bool = jvm + .invoke_virtual(&value, &value.class_definition().name(), "matches", "(Ljava/lang/String;)Z", (regex,)) + .await?; assert_eq!(string_matches, direct_matches); let regex = JavaLangString::from_rust_string(&jvm, r"([a-z]+)(\d+)").await?; @@ -109,14 +129,27 @@ async fn string_regex_methods_match_direct_pattern_and_matcher_results() -> Resu .await?; let input: ClassInstanceRef = value.clone().into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; let direct_first: ClassInstanceRef = jvm - .invoke_virtual(&matcher, "replaceFirst", "(Ljava/lang/String;)Ljava/lang/String;", (replacement.clone(),)) + .invoke_virtual( + &matcher, + "java/util/regex/Matcher", + "replaceFirst", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement.clone(),), + ) .await?; let string_first: ClassInstanceRef = jvm .invoke_virtual( &value, + &value.class_definition().name(), "replaceFirst", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (regex.clone(), replacement.clone()), @@ -129,14 +162,27 @@ async fn string_regex_methods_match_direct_pattern_and_matcher_results() -> Resu let input: ClassInstanceRef = value.clone().into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; let direct_all: ClassInstanceRef = jvm - .invoke_virtual(&matcher, "replaceAll", "(Ljava/lang/String;)Ljava/lang/String;", (replacement.clone(),)) + .invoke_virtual( + &matcher, + "java/util/regex/Matcher", + "replaceAll", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement.clone(),), + ) .await?; let string_all: ClassInstanceRef = jvm .invoke_virtual( &value, + &value.class_definition().name(), "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (regex, replacement), @@ -166,10 +212,22 @@ async fn string_split_overloads_match_direct_pattern_results() -> Result<()> { let input: ClassInstanceRef = value.clone().into(); let direct: ClassInstanceRef> = jvm - .invoke_virtual(&pattern, "split", "(Ljava/lang/CharSequence;)[Ljava/lang/String;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;)[Ljava/lang/String;", + (input,), + ) .await?; let convenient: ClassInstanceRef> = jvm - .invoke_virtual(&value, "split", "(Ljava/lang/String;)[Ljava/lang/String;", (regex.clone(),)) + .invoke_virtual( + &value, + &value.class_definition().name(), + "split", + "(Ljava/lang/String;)[Ljava/lang/String;", + (regex.clone(),), + ) .await?; let direct = jvm .load_array::>(&direct, 0, jvm.array_length(&direct).await?) @@ -187,10 +245,22 @@ async fn string_split_overloads_match_direct_pattern_results() -> Result<()> { let input: ClassInstanceRef = value.clone().into(); let direct: ClassInstanceRef> = jvm - .invoke_virtual(&pattern, "split", "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", (input, -1)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", + (input, -1), + ) .await?; let convenient: ClassInstanceRef> = jvm - .invoke_virtual(&value, "split", "(Ljava/lang/String;I)[Ljava/lang/String;", (regex, -1)) + .invoke_virtual( + &value, + &value.class_definition().name(), + "split", + "(Ljava/lang/String;I)[Ljava/lang/String;", + (regex, -1), + ) .await?; let direct = jvm .load_array::>(&direct, 0, jvm.array_length(&direct).await?) @@ -218,14 +288,27 @@ async fn string_regex_methods_preserve_compile_and_replacement_exception_order() let null_replacement: ClassInstanceRef = None.into(); for result in [ - jvm.invoke_virtual::<_, bool>(&value, "matches", "(Ljava/lang/String;)Z", (invalid.clone(),)) - .await - .map(|_| ()), - jvm.invoke_virtual::<_, ClassInstanceRef>>(&value, "split", "(Ljava/lang/String;)[Ljava/lang/String;", (invalid.clone(),)) - .await - .map(|_| ()), + jvm.invoke_virtual::<_, bool>( + &value, + &value.class_definition().name(), + "matches", + "(Ljava/lang/String;)Z", + (invalid.clone(),), + ) + .await + .map(|_| ()), + jvm.invoke_virtual::<_, ClassInstanceRef>>( + &value, + &value.class_definition().name(), + "split", + "(Ljava/lang/String;)[Ljava/lang/String;", + (invalid.clone(),), + ) + .await + .map(|_| ()), jvm.invoke_virtual::<_, ClassInstanceRef>( &value, + &value.class_definition().name(), "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (invalid.clone(), null_replacement.clone()), @@ -240,11 +323,18 @@ async fn string_regex_methods_preserve_compile_and_replacement_exception_order() } for result in [ - jvm.invoke_virtual::<_, bool>(&value, "matches", "(Ljava/lang/String;)Z", (null_regex.clone(),)) - .await - .map(|_| ()), + jvm.invoke_virtual::<_, bool>( + &value, + &value.class_definition().name(), + "matches", + "(Ljava/lang/String;)Z", + (null_regex.clone(),), + ) + .await + .map(|_| ()), jvm.invoke_virtual::<_, ClassInstanceRef>>( &value, + &value.class_definition().name(), "split", "(Ljava/lang/String;I)[Ljava/lang/String;", (null_regex.clone(), 0), @@ -253,6 +343,7 @@ async fn string_regex_methods_preserve_compile_and_replacement_exception_order() .map(|_| ()), jvm.invoke_virtual::<_, ClassInstanceRef>( &value, + &value.class_definition().name(), "replaceFirst", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (null_regex.clone(), null_replacement.clone()), @@ -270,6 +361,7 @@ async fn string_regex_methods_preserve_compile_and_replacement_exception_order() let result: Result> = jvm .invoke_virtual( &value, + &value.class_definition().name(), "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (matching, null_replacement.clone()), @@ -285,6 +377,7 @@ async fn string_regex_methods_preserve_compile_and_replacement_exception_order() let unchanged: ClassInstanceRef = jvm .invoke_virtual( &value, + &value.class_definition().name(), name, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (no_match.clone(), null_replacement.clone()), @@ -305,6 +398,7 @@ async fn string_regex_methods_preserve_utf16_text() -> Result<()> { let replaced: ClassInstanceRef = jvm .invoke_virtual( &value, + &value.class_definition().name(), "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (digits, replacement), @@ -314,7 +408,13 @@ async fn string_regex_methods_preserve_utf16_text() -> Result<()> { let separator = JavaLangString::from_rust_string(&jvm, "😀").await?; let parts: ClassInstanceRef> = jvm - .invoke_virtual(&value, "split", "(Ljava/lang/String;I)[Ljava/lang/String;", (separator, -1)) + .invoke_virtual( + &value, + &value.class_definition().name(), + "split", + "(Ljava/lang/String;I)[Ljava/lang/String;", + (separator, -1), + ) .await?; let parts = jvm .load_array::>(&parts, 0, jvm.array_length(&parts).await?) @@ -349,7 +449,13 @@ async fn test_string_concat() -> Result<()> { let string2 = JavaLangString::from_rust_string(&jvm, "test2").await?; let result = jvm - .invoke_virtual(&string1, "concat", "(Ljava/lang/String;)Ljava/lang/String;", (string2,)) + .invoke_virtual( + &string1, + &string1.class_definition().name(), + "concat", + "(Ljava/lang/String;)Ljava/lang/String;", + (string2,), + ) .await?; let string = JavaLangString::to_rust_string(&jvm, &result).await?; @@ -364,15 +470,21 @@ async fn test_hash_code() -> Result<()> { let jvm = test_jvm().await?; let string = JavaLangString::from_rust_string(&jvm, "Hi").await?; - let hash_code: i32 = jvm.invoke_virtual(&string, "hashCode", "()I", ()).await?; + let hash_code: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "hashCode", "()I", ()) + .await?; assert_eq!(hash_code, 2337); let string1 = JavaLangString::from_rust_string(&jvm, "test").await?; - let hash_code1: i32 = jvm.invoke_virtual(&string1, "hashCode", "()I", ()).await?; + let hash_code1: i32 = jvm + .invoke_virtual(&string1, &string1.class_definition().name(), "hashCode", "()I", ()) + .await?; assert_eq!(hash_code1, 3556498); let string2 = JavaLangString::from_rust_string(&jvm, "Hi").await?; - let hash_code: i32 = jvm.invoke_virtual(&string2, "hashCode", "()I", ()).await?; + let hash_code: i32 = jvm + .invoke_virtual(&string2, &string2.class_definition().name(), "hashCode", "()I", ()) + .await?; assert_eq!(hash_code, 2337); Ok(()) @@ -385,40 +497,76 @@ async fn test_index_of() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "123 테스트 456").await?; let pattern = JavaLangString::from_rust_string(&jvm, "테스트").await?; - let index: i32 = jvm.invoke_virtual(&string, "indexOf", "(Ljava/lang/String;)I", (pattern,)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "indexOf", "(Ljava/lang/String;)I", (pattern,)) + .await?; assert_eq!(index, 4); let pattern = JavaLangString::from_rust_string(&jvm, "456").await?; let index: i32 = jvm - .invoke_virtual(&string, "indexOf", "(Ljava/lang/String;)I", (pattern.clone(),)) + .invoke_virtual( + &string, + &string.class_definition().name(), + "indexOf", + "(Ljava/lang/String;)I", + (pattern.clone(),), + ) .await?; assert_eq!(index, 8); let index: i32 = jvm - .invoke_virtual(&string, "indexOf", "(Ljava/lang/String;I)I", (pattern.clone(), 5)) + .invoke_virtual( + &string, + &string.class_definition().name(), + "indexOf", + "(Ljava/lang/String;I)I", + (pattern.clone(), 5), + ) .await?; assert_eq!(index, 8); let pattern = JavaLangString::from_rust_string(&jvm, "123").await?; let index: i32 = jvm - .invoke_virtual(&string, "indexOf", "(Ljava/lang/String;)I", (pattern.clone(),)) + .invoke_virtual( + &string, + &string.class_definition().name(), + "indexOf", + "(Ljava/lang/String;)I", + (pattern.clone(),), + ) .await?; assert_eq!(index, 0); - let index: i32 = jvm.invoke_virtual(&string, "indexOf", "(Ljava/lang/String;I)I", (pattern, 2)).await?; + let index: i32 = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "indexOf", + "(Ljava/lang/String;I)I", + (pattern, 2), + ) + .await?; assert_eq!(index, -1); let pattern = JavaLangString::from_rust_string(&jvm, "789").await?; - let index: i32 = jvm.invoke_virtual(&string, "indexOf", "(Ljava/lang/String;)I", (pattern,)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "indexOf", "(Ljava/lang/String;)I", (pattern,)) + .await?; assert_eq!(index, -1); - let index: i32 = jvm.invoke_virtual(&string, "indexOf", "(I)I", (52,)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "indexOf", "(I)I", (52,)) + .await?; assert_eq!(index, 8); - let index: i32 = jvm.invoke_virtual(&string, "indexOf", "(II)I", (52, 8)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "indexOf", "(II)I", (52, 8)) + .await?; assert_eq!(index, 8); - let index: i32 = jvm.invoke_virtual(&string, "indexOf", "(II)I", (52, 9)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "indexOf", "(II)I", (52, 9)) + .await?; assert_eq!(index, -1); Ok(()) @@ -431,27 +579,75 @@ async fn test_starts_with() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "123 테스트 456").await?; let pattern = JavaLangString::from_rust_string(&jvm, "123").await?; - let result: bool = jvm.invoke_virtual(&string, "startsWith", "(Ljava/lang/String;)Z", (pattern,)).await?; + let result: bool = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "startsWith", + "(Ljava/lang/String;)Z", + (pattern,), + ) + .await?; assert!(result); let pattern = JavaLangString::from_rust_string(&jvm, "456").await?; - let result: bool = jvm.invoke_virtual(&string, "startsWith", "(Ljava/lang/String;)Z", (pattern,)).await?; + let result: bool = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "startsWith", + "(Ljava/lang/String;)Z", + (pattern,), + ) + .await?; assert!(!result); let pattern = JavaLangString::from_rust_string(&jvm, "123 테스트").await?; - let result: bool = jvm.invoke_virtual(&string, "startsWith", "(Ljava/lang/String;)Z", (pattern,)).await?; + let result: bool = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "startsWith", + "(Ljava/lang/String;)Z", + (pattern,), + ) + .await?; assert!(result); let pattern = JavaLangString::from_rust_string(&jvm, "테스트").await?; - let result: bool = jvm.invoke_virtual(&string, "startsWith", "(Ljava/lang/String;)Z", (pattern,)).await?; + let result: bool = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "startsWith", + "(Ljava/lang/String;)Z", + (pattern,), + ) + .await?; assert!(!result); let pattern = JavaLangString::from_rust_string(&jvm, "테스트").await?; - let result: bool = jvm.invoke_virtual(&string, "startsWith", "(Ljava/lang/String;I)Z", (pattern, 4)).await?; + let result: bool = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "startsWith", + "(Ljava/lang/String;I)Z", + (pattern, 4), + ) + .await?; assert!(result); let pattern = JavaLangString::from_rust_string(&jvm, "테스트").await?; - let result: bool = jvm.invoke_virtual(&string, "startsWith", "(Ljava/lang/String;I)Z", (pattern, 5)).await?; + let result: bool = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "startsWith", + "(Ljava/lang/String;I)Z", + (pattern, 5), + ) + .await?; assert!(!result); Ok(()) @@ -463,13 +659,21 @@ async fn test_last_index_of() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "456 가나다 456").await?; - let index: i32 = jvm.invoke_virtual(&string, "lastIndexOf", "(I)I", (b'4' as i32,)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "lastIndexOf", "(I)I", (b'4' as i32,)) + .await?; assert_eq!(index, 8); - let index: i32 = jvm.invoke_virtual(&string, "lastIndexOf", "(I)I", (b'5' as i32,)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "lastIndexOf", "(I)I", (b'5' as i32,)) + .await?; assert_eq!(index, 9); - let index: i32 = jvm.invoke_virtual(&string, "lastIndexOf", "(I)I", (b'6' as i32,)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "lastIndexOf", "(I)I", (b'6' as i32,)) + .await?; assert_eq!(index, 10); - let index: i32 = jvm.invoke_virtual(&string, "lastIndexOf", "(I)I", (b'7' as i32,)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "lastIndexOf", "(I)I", (b'7' as i32,)) + .await?; assert_eq!(index, -1); Ok(()) @@ -484,7 +688,13 @@ async fn test_get_chars() -> Result<()> { let char_array = jvm.instantiate_array("[C", 11).await?; let _: () = jvm - .invoke_virtual(&string, "getChars", "(II[CI)V", (0i32, 11i32, char_array.clone(), 0i32)) + .invoke_virtual( + &string, + &string.class_definition().name(), + "getChars", + "(II[CI)V", + (0i32, 11i32, char_array.clone(), 0i32), + ) .await?; let chars = jvm.load_array::(&char_array, 0, 11).await?; let rust_string = String::from_utf16(&chars).unwrap(); @@ -493,7 +703,13 @@ async fn test_get_chars() -> Result<()> { let partial_array = jvm.instantiate_array("[C", 4).await?; let _: () = jvm - .invoke_virtual(&string, "getChars", "(II[CI)V", (7i32, 11i32, partial_array.clone(), 0i32)) + .invoke_virtual( + &string, + &string.class_definition().name(), + "getChars", + "(II[CI)V", + (7i32, 11i32, partial_array.clone(), 0i32), + ) .await?; let chars = jvm.load_array::(&partial_array, 0, 4).await?; let rust_string = String::from_utf16(&chars).unwrap(); @@ -509,11 +725,15 @@ async fn test_ends_with() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "Hello, 테스트!").await?; let suffix = JavaLangString::from_rust_string(&jvm, "테스트!").await?; - let result: bool = jvm.invoke_virtual(&string, "endsWith", "(Ljava/lang/String;)Z", (suffix,)).await?; + let result: bool = jvm + .invoke_virtual(&string, &string.class_definition().name(), "endsWith", "(Ljava/lang/String;)Z", (suffix,)) + .await?; assert!(result); let suffix = JavaLangString::from_rust_string(&jvm, "Hello").await?; - let result: bool = jvm.invoke_virtual(&string, "endsWith", "(Ljava/lang/String;)Z", (suffix,)).await?; + let result: bool = jvm + .invoke_virtual(&string, &string.class_definition().name(), "endsWith", "(Ljava/lang/String;)Z", (suffix,)) + .await?; assert!(!result); Ok(()) @@ -525,12 +745,16 @@ async fn test_equals_ignore_case() -> Result<()> { let a = JavaLangString::from_rust_string(&jvm, "Hello").await?; let b = JavaLangString::from_rust_string(&jvm, "HELLO").await?; - let result: bool = jvm.invoke_virtual(&a, "equalsIgnoreCase", "(Ljava/lang/String;)Z", (b,)).await?; + let result: bool = jvm + .invoke_virtual(&a, &a.class_definition().name(), "equalsIgnoreCase", "(Ljava/lang/String;)Z", (b,)) + .await?; assert!(result); let a = JavaLangString::from_rust_string(&jvm, "Hello").await?; let b = JavaLangString::from_rust_string(&jvm, "World").await?; - let result: bool = jvm.invoke_virtual(&a, "equalsIgnoreCase", "(Ljava/lang/String;)Z", (b,)).await?; + let result: bool = jvm + .invoke_virtual(&a, &a.class_definition().name(), "equalsIgnoreCase", "(Ljava/lang/String;)Z", (b,)) + .await?; assert!(!result); Ok(()) @@ -541,7 +765,9 @@ async fn test_to_lower_case() -> Result<()> { let jvm = test_jvm().await?; let string = JavaLangString::from_rust_string(&jvm, "HELLO 테스트").await?; - let result = jvm.invoke_virtual(&string, "toLowerCase", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&string, &string.class_definition().name(), "toLowerCase", "()Ljava/lang/String;", ()) + .await?; let result_string = JavaLangString::to_rust_string(&jvm, &result).await?; assert_eq!(result_string, "hello 테스트"); @@ -554,7 +780,13 @@ async fn test_replace() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "a.b.c.d").await?; let result = jvm - .invoke_virtual(&string, "replace", "(CC)Ljava/lang/String;", (b'.' as u16, b'/' as u16)) + .invoke_virtual( + &string, + &string.class_definition().name(), + "replace", + "(CC)Ljava/lang/String;", + (b'.' as u16, b'/' as u16), + ) .await?; let result_string = JavaLangString::to_rust_string(&jvm, &result).await?; assert_eq!(result_string, "a/b/c/d"); @@ -570,17 +802,35 @@ async fn test_region_matches() -> Result<()> { let b = JavaLangString::from_rust_string(&jvm, "WORLD!!!").await?; let result: bool = jvm - .invoke_virtual(&a, "regionMatches", "(ZILjava/lang/String;II)Z", (false, 6i32, b.clone(), 0i32, 5i32)) + .invoke_virtual( + &a, + &a.class_definition().name(), + "regionMatches", + "(ZILjava/lang/String;II)Z", + (false, 6i32, b.clone(), 0i32, 5i32), + ) .await?; assert!(!result); let result: bool = jvm - .invoke_virtual(&a, "regionMatches", "(ZILjava/lang/String;II)Z", (true, 6i32, b.clone(), 0i32, 5i32)) + .invoke_virtual( + &a, + &a.class_definition().name(), + "regionMatches", + "(ZILjava/lang/String;II)Z", + (true, 6i32, b.clone(), 0i32, 5i32), + ) .await?; assert!(result); let result: bool = jvm - .invoke_virtual(&a, "regionMatches", "(ZILjava/lang/String;II)Z", (false, 0i32, b, 0i32, 3i32)) + .invoke_virtual( + &a, + &a.class_definition().name(), + "regionMatches", + "(ZILjava/lang/String;II)Z", + (false, 0i32, b, 0i32, 3i32), + ) .await?; assert!(!result); @@ -593,13 +843,19 @@ async fn test_last_index_of_from() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "abcabc").await?; - let index: i32 = jvm.invoke_virtual(&string, "lastIndexOf", "(II)I", (b'a' as i32, 5i32)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "lastIndexOf", "(II)I", (b'a' as i32, 5i32)) + .await?; assert_eq!(index, 3); - let index: i32 = jvm.invoke_virtual(&string, "lastIndexOf", "(II)I", (b'a' as i32, 2i32)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "lastIndexOf", "(II)I", (b'a' as i32, 2i32)) + .await?; assert_eq!(index, 0); - let index: i32 = jvm.invoke_virtual(&string, "lastIndexOf", "(II)I", (b'z' as i32, 5i32)).await?; + let index: i32 = jvm + .invoke_virtual(&string, &string.class_definition().name(), "lastIndexOf", "(II)I", (b'z' as i32, 5i32)) + .await?; assert_eq!(index, -1); Ok(()) @@ -679,7 +935,15 @@ async fn test_substring_invalid_range() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "hello").await?; for (begin, end) in [(3i32, 1i32), (0, 10), (-1, 3)] { - let result: Result> = jvm.invoke_virtual(&string, "substring", "(II)Ljava/lang/String;", (begin, end)).await; + let result: Result> = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "substring", + "(II)Ljava/lang/String;", + (begin, end), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException for ({begin}, {end}), got {:?}", result); @@ -697,7 +961,15 @@ async fn test_get_bytes_unmappable_charset() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "a한b").await?; let charset = JavaLangString::from_rust_string(&jvm, "ISO-8859-1").await?; - let bytes = jvm.invoke_virtual(&string, "getBytes", "(Ljava/lang/String;)[B", (charset,)).await?; + let bytes = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "getBytes", + "(Ljava/lang/String;)[B", + (charset,), + ) + .await?; let bytes = jvm.load_array::(&bytes, 0, 3).await?; assert_eq!(bytes, [0x61, 0x3f, 0x62]); @@ -712,13 +984,19 @@ async fn test_substring_utf16_indices() -> Result<()> { // "a😀b" has Java length 4: the emoji is a surrogate pair let string = JavaLangString::from_rust_string(&jvm, "a😀b").await?; - let full: ClassInstanceRef = jvm.invoke_virtual(&string, "substring", "(II)Ljava/lang/String;", (0, 4)).await?; + let full: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "substring", "(II)Ljava/lang/String;", (0, 4)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &full).await?, "a😀b"); - let emoji: ClassInstanceRef = jvm.invoke_virtual(&string, "substring", "(II)Ljava/lang/String;", (1, 3)).await?; + let emoji: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "substring", "(II)Ljava/lang/String;", (1, 3)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &emoji).await?, "😀"); - let tail: ClassInstanceRef = jvm.invoke_virtual(&string, "substring", "(I)Ljava/lang/String;", (3,)).await?; + let tail: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "substring", "(I)Ljava/lang/String;", (3,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &tail).await?, "b"); Ok(()) @@ -731,7 +1009,15 @@ async fn test_get_bytes_ascii_replaces_non_ascii() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "aé한").await?; let charset = JavaLangString::from_rust_string(&jvm, "US-ASCII").await?; - let bytes = jvm.invoke_virtual(&string, "getBytes", "(Ljava/lang/String;)[B", (charset,)).await?; + let bytes = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "getBytes", + "(Ljava/lang/String;)[B", + (charset,), + ) + .await?; let bytes = jvm.load_array::(&bytes, 0, 3).await?; assert_eq!(bytes, [0x61, 0x3f, 0x3f]); @@ -748,24 +1034,45 @@ async fn test_index_of_uses_utf16_indices_and_handles_empty_patterns() -> Result let tail = JavaLangString::from_rust_string(&jvm, "b").await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "indexOf", "(Ljava/lang/String;)I", (emoji,)) + jvm.invoke_virtual::<_, i32>(&string, &string.class_definition().name(), "indexOf", "(Ljava/lang/String;)I", (emoji,)) .await?, 1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "indexOf", "(Ljava/lang/String;)I", (tail,)).await?, + jvm.invoke_virtual::<_, i32>(&string, &string.class_definition().name(), "indexOf", "(Ljava/lang/String;)I", (tail,)) + .await?, 3 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&string, "indexOf", "(II)I", (b'b' as i32, -10)).await?, 3); - assert_eq!(jvm.invoke_virtual::<_, i32>(&string, "lastIndexOf", "(I)I", (b'b' as i32,)).await?, 3); assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "indexOf", "(Ljava/lang/String;I)I", (empty.clone(), -10)) + jvm.invoke_virtual::<_, i32>(&string, &string.class_definition().name(), "indexOf", "(II)I", (b'b' as i32, -10)) .await?, - 0 + 3 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "indexOf", "(Ljava/lang/String;I)I", (empty, 99)) + jvm.invoke_virtual::<_, i32>(&string, &string.class_definition().name(), "lastIndexOf", "(I)I", (b'b' as i32,)) .await?, + 3 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &string, + &string.class_definition().name(), + "indexOf", + "(Ljava/lang/String;I)I", + (empty.clone(), -10) + ) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &string, + &string.class_definition().name(), + "indexOf", + "(Ljava/lang/String;I)I", + (empty, 99) + ) + .await?, 4 ); @@ -779,7 +1086,13 @@ async fn test_unknown_string_charset_throws_unsupported_encoding() -> Result<()> let charset = JavaLangString::from_rust_string(&jvm, "not-a-charset").await?; let result: Result>> = jvm - .invoke_virtual(&string, "getBytes", "(Ljava/lang/String;)[B", (charset.clone(),)) + .invoke_virtual( + &string, + &string.class_definition().name(), + "getBytes", + "(Ljava/lang/String;)[B", + (charset.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("unknown charset must throw UnsupportedEncodingException"); @@ -801,12 +1114,16 @@ async fn test_unknown_string_charset_throws_unsupported_encoding() -> Result<()> async fn test_trim_uses_java_control_character_boundary() -> Result<()> { let jvm = test_jvm().await?; let string = JavaLangString::from_rust_string(&jvm, " \t\u{a0}value\u{a0}\n ").await?; - let trimmed: ClassInstanceRef = jvm.invoke_virtual(&string, "trim", "()Ljava/lang/String;", ()).await?; + let trimmed: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "trim", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &trimmed).await?, "\u{a0}value\u{a0}"); let unchanged = JavaLangString::from_rust_string(&jvm, "value").await?; - let same: ClassInstanceRef = jvm.invoke_virtual(&unchanged, "trim", "()Ljava/lang/String;", ()).await?; + let same: ClassInstanceRef = jvm + .invoke_virtual(&unchanged, "java/lang/String", "trim", "()Ljava/lang/String;", ()) + .await?; assert_eq!(unchanged.identity(), same.identity()); Ok(()) @@ -817,7 +1134,9 @@ async fn test_substring_shares_parent_value() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "HelloWorld").await?; - let child: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 5)).await?; + let child: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 5)) + .await?; let parent_value: ClassInstanceRef> = jvm.get_field(&parent, "value", "[C").await?; let child_value: ClassInstanceRef> = jvm.get_field(&child, "value", "[C").await?; @@ -826,7 +1145,9 @@ async fn test_substring_shares_parent_value() -> Result<()> { assert_eq!(jvm.get_field::(&child, "count", "I").await?, 3); assert_eq!(JavaLangString::to_rust_string(&jvm, &child).await?, "llo"); - let tail: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(I)Ljava/lang/String;", (5,)).await?; + let tail: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(I)Ljava/lang/String;", (5,)) + .await?; let tail_value: ClassInstanceRef> = jvm.get_field(&tail, "value", "[C").await?; assert_eq!(parent_value.identity(), tail_value.identity()); assert_eq!(jvm.get_field::(&tail, "offset", "I").await?, 5); @@ -842,10 +1163,14 @@ async fn test_full_range_substring_returns_this() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "Hello").await?; - let same: ClassInstanceRef = jvm.invoke_virtual(&string, "substring", "(I)Ljava/lang/String;", (0,)).await?; + let same: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "substring", "(I)Ljava/lang/String;", (0,)) + .await?; assert_eq!(string.identity(), same.identity()); - let same: ClassInstanceRef = jvm.invoke_virtual(&string, "substring", "(II)Ljava/lang/String;", (0, 5)).await?; + let same: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "substring", "(II)Ljava/lang/String;", (0, 5)) + .await?; assert_eq!(string.identity(), same.identity()); Ok(()) @@ -856,16 +1181,28 @@ async fn test_nested_substring_shares_root_value() -> Result<()> { let jvm = test_jvm().await?; let root = JavaLangString::from_rust_string(&jvm, "abcdefghij").await?; - let outer: ClassInstanceRef = jvm.invoke_virtual(&root, "substring", "(II)Ljava/lang/String;", (2, 8)).await?; - let inner: ClassInstanceRef = jvm.invoke_virtual(&outer, "substring", "(II)Ljava/lang/String;", (1, 3)).await?; + let outer: ClassInstanceRef = jvm + .invoke_virtual(&root, &root.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 8)) + .await?; + let inner: ClassInstanceRef = jvm + .invoke_virtual(&outer, "java/lang/String", "substring", "(II)Ljava/lang/String;", (1, 3)) + .await?; let root_value: ClassInstanceRef> = jvm.get_field(&root, "value", "[C").await?; let inner_value: ClassInstanceRef> = jvm.get_field(&inner, "value", "[C").await?; assert_eq!(root_value.identity(), inner_value.identity()); assert_eq!(jvm.get_field::(&inner, "offset", "I").await?, 3); assert_eq!(jvm.get_field::(&inner, "count", "I").await?, 2); - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&inner, "charAt", "(I)C", (0,)).await?, b'd' as JavaChar); - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&inner, "charAt", "(I)C", (1,)).await?, b'e' as JavaChar); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&inner, "java/lang/String", "charAt", "(I)C", (0,)) + .await?, + b'd' as JavaChar + ); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&inner, "java/lang/String", "charAt", "(I)C", (1,)) + .await?, + b'e' as JavaChar + ); Ok(()) } @@ -894,7 +1231,9 @@ async fn test_to_char_array_returns_copy() -> Result<()> { let jvm = test_jvm().await?; let string = JavaLangString::from_rust_string(&jvm, "abc").await?; - let mut chars: ClassInstanceRef> = jvm.invoke_virtual(&string, "toCharArray", "()[C", ()).await?; + let mut chars: ClassInstanceRef> = jvm + .invoke_virtual(&string, &string.class_definition().name(), "toCharArray", "()[C", ()) + .await?; let value: ClassInstanceRef> = jvm.get_field(&string, "value", "[C").await?; assert_ne!(chars.identity(), value.identity()); @@ -911,8 +1250,10 @@ async fn test_to_char_array_on_substring_covers_logical_range_only() -> Result<( let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "HelloWorld").await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 5)).await?; - let chars: ClassInstanceRef> = jvm.invoke_virtual(&sub, "toCharArray", "()[C", ()).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 5)) + .await?; + let chars: ClassInstanceRef> = jvm.invoke_virtual(&sub, "java/lang/String", "toCharArray", "()[C", ()).await?; assert_eq!(jvm.array_length(&chars).await?, 3); assert_eq!(jvm.load_array::(&chars, 0, 3).await?, "llo".encode_utf16().collect::>()); @@ -925,14 +1266,24 @@ async fn test_char_at_and_get_chars_on_substring_check_bounds() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 7)) + .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub, "length", "()I", ()).await?, 5); - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&sub, "charAt", "(I)C", (0,)).await?, b'H' as JavaChar); - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&sub, "charAt", "(I)C", (4,)).await?, b'o' as JavaChar); + assert_eq!(jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "length", "()I", ()).await?, 5); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&sub, "java/lang/String", "charAt", "(I)C", (0,)) + .await?, + b'H' as JavaChar + ); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&sub, "java/lang/String", "charAt", "(I)C", (4,)) + .await?, + b'o' as JavaChar + ); for index in [5, -1] { - let result: Result = jvm.invoke_virtual(&sub, "charAt", "(I)C", (index,)).await; + let result: Result = jvm.invoke_virtual(&sub, "java/lang/String", "charAt", "(I)C", (index,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("charAt({index}) must throw"); }; @@ -940,11 +1291,13 @@ async fn test_char_at_and_get_chars_on_substring_check_bounds() -> Result<()> { } let dst = jvm.instantiate_array("C", 3).await?; - let _: () = jvm.invoke_virtual(&sub, "getChars", "(II[CI)V", (1, 4, dst.clone(), 0)).await?; + let _: () = jvm + .invoke_virtual(&sub, "java/lang/String", "getChars", "(II[CI)V", (1, 4, dst.clone(), 0)) + .await?; assert_eq!(jvm.load_array::(&dst, 0, 3).await?, "ell".encode_utf16().collect::>()); let dst = jvm.instantiate_array("C", 8).await?; - let result: Result<()> = jvm.invoke_virtual(&sub, "getChars", "(II[CI)V", (1, 6, dst, 0)).await; + let result: Result<()> = jvm.invoke_virtual(&sub, "java/lang/String", "getChars", "(II[CI)V", (1, 6, dst, 0)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("getChars beyond count must throw"); }; @@ -958,28 +1311,46 @@ async fn test_search_on_substring_does_not_see_parent_data() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 7)) + .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub, "indexOf", "(I)I", (b'l' as i32,)).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub, "indexOf", "(I)I", (b'x' as i32,)).await?, -1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub, "lastIndexOf", "(I)I", (b'l' as i32,)).await?, 3); - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub, "lastIndexOf", "(II)I", (b'l' as i32, 2)).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "indexOf", "(I)I", (b'l' as i32,)) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "indexOf", "(I)I", (b'x' as i32,)) + .await?, + -1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "lastIndexOf", "(I)I", (b'l' as i32,)) + .await?, + 3 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "lastIndexOf", "(II)I", (b'l' as i32, 2)) + .await?, + 2 + ); let pattern = JavaLangString::from_rust_string(&jvm, "llo").await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&sub, "indexOf", "(Ljava/lang/String;)I", (pattern.clone(),)) + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "indexOf", "(Ljava/lang/String;)I", (pattern.clone(),)) .await?, 2 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&sub, "lastIndexOf", "(Ljava/lang/String;)I", (pattern,)) + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "lastIndexOf", "(Ljava/lang/String;)I", (pattern,)) .await?, 2 ); let outside = JavaLangString::from_rust_string(&jvm, "y").await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&sub, "lastIndexOf", "(Ljava/lang/String;)I", (outside,)) + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "lastIndexOf", "(Ljava/lang/String;)I", (outside,)) .await?, -1 ); @@ -992,36 +1363,45 @@ async fn test_equality_and_hash_on_substring() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 7)) + .await?; let hello = JavaLangString::from_rust_string(&jvm, "Hello").await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&sub, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&hello, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "hashCode", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&hello, &hello.class_definition().name(), "hashCode", "()I", ()) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&sub, "equals", "(Ljava/lang/Object;)Z", (hello.clone(),)) + jvm.invoke_virtual::<_, bool>(&sub, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", (hello.clone(),)) .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&sub, "equals", "(Ljava/lang/Object;)Z", (sub.clone(),)) + jvm.invoke_virtual::<_, bool>(&sub, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", (sub.clone(),)) .await? ); let prefix = JavaLangString::from_rust_string(&jvm, "xxHel").await?; - assert!(!jvm.invoke_virtual::<_, bool>(&sub, "equals", "(Ljava/lang/Object;)Z", (prefix,)).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&sub, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", (prefix,)) + .await? + ); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - assert!(!jvm.invoke_virtual::<_, bool>(&sub, "equals", "(Ljava/lang/Object;)Z", (object,)).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&sub, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", (object,)) + .await? + ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&sub, "compareTo", "(Ljava/lang/String;)I", (hello.clone(),)) + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "compareTo", "(Ljava/lang/String;)I", (hello.clone(),)) .await?, 0 ); let upper = JavaLangString::from_rust_string(&jvm, "HELLO").await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&sub, "compareToIgnoreCase", "(Ljava/lang/String;)I", (upper,)) + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "compareToIgnoreCase", "(Ljava/lang/String;)I", (upper,)) .await?, 0 ); @@ -1034,38 +1414,46 @@ async fn test_string_api_on_substring() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 7)) + .await?; let prefix = JavaLangString::from_rust_string(&jvm, "He").await?; assert!( - jvm.invoke_virtual::<_, bool>(&sub, "startsWith", "(Ljava/lang/String;)Z", (prefix,)) + jvm.invoke_virtual::<_, bool>(&sub, "java/lang/String", "startsWith", "(Ljava/lang/String;)Z", (prefix,)) .await? ); let suffix = JavaLangString::from_rust_string(&jvm, "lo").await?; assert!( - jvm.invoke_virtual::<_, bool>(&sub, "endsWith", "(Ljava/lang/String;)Z", (suffix,)) + jvm.invoke_virtual::<_, bool>(&sub, "java/lang/String", "endsWith", "(Ljava/lang/String;)Z", (suffix,)) .await? ); let hello = JavaLangString::from_rust_string(&jvm, "Hello").await?; assert!( - jvm.invoke_virtual::<_, bool>(&sub, "regionMatches", "(ILjava/lang/String;II)Z", (0, hello, 0, 5)) + jvm.invoke_virtual::<_, bool>(&sub, "java/lang/String", "regionMatches", "(ILjava/lang/String;II)Z", (0, hello, 0, 5)) .await? ); let replaced: ClassInstanceRef = jvm - .invoke_virtual(&sub, "replace", "(CC)Ljava/lang/String;", (b'l' as JavaChar, b'L' as JavaChar)) + .invoke_virtual( + &sub, + "java/lang/String", + "replace", + "(CC)Ljava/lang/String;", + (b'l' as JavaChar, b'L' as JavaChar), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &replaced).await?, "HeLLo"); let other = JavaLangString::from_rust_string(&jvm, "!").await?; let concat: ClassInstanceRef = jvm - .invoke_virtual(&sub, "concat", "(Ljava/lang/String;)Ljava/lang/String;", (other,)) + .invoke_virtual(&sub, "java/lang/String", "concat", "(Ljava/lang/String;)Ljava/lang/String;", (other,)) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &concat).await?, "Hello!"); - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&sub, "getBytes", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm.invoke_virtual(&sub, "java/lang/String", "getBytes", "()[B", ()).await?; assert_eq!( jvm.load_array::(&bytes, 0, 5).await?, b"Hello".iter().map(|&b| b as i8).collect::>() @@ -1079,10 +1467,12 @@ async fn test_trim_on_substring_shares_buffer() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "xx hi yy").await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 8)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 8)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &sub).await?, " hi "); - let trimmed: ClassInstanceRef = jvm.invoke_virtual(&sub, "trim", "()Ljava/lang/String;", ()).await?; + let trimmed: ClassInstanceRef = jvm.invoke_virtual(&sub, "java/lang/String", "trim", "()Ljava/lang/String;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &trimmed).await?, "hi"); let parent_value: ClassInstanceRef> = jvm.get_field(&parent, "value", "[C").await?; @@ -1091,8 +1481,12 @@ async fn test_trim_on_substring_shares_buffer() -> Result<()> { assert_eq!(jvm.get_field::(&trimmed, "offset", "I").await?, 4); assert_eq!(jvm.get_field::(&trimmed, "count", "I").await?, 2); - let no_trim: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (4, 6)).await?; - let same: ClassInstanceRef = jvm.invoke_virtual(&no_trim, "trim", "()Ljava/lang/String;", ()).await?; + let no_trim: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (4, 6)) + .await?; + let same: ClassInstanceRef = jvm + .invoke_virtual(&no_trim, "java/lang/String", "trim", "()Ljava/lang/String;", ()) + .await?; assert_eq!(no_trim.identity(), same.identity()); Ok(()) @@ -1103,22 +1497,30 @@ async fn test_substring_bounds_on_substring() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 7)) + .await?; - let result: Result> = jvm.invoke_virtual(&sub, "substring", "(I)Ljava/lang/String;", (-1,)).await; + let result: Result> = jvm + .invoke_virtual(&sub, "java/lang/String", "substring", "(I)Ljava/lang/String;", (-1,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("substring(-1) must throw"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let result: Result> = jvm.invoke_virtual(&sub, "substring", "(I)Ljava/lang/String;", (6,)).await; + let result: Result> = jvm + .invoke_virtual(&sub, "java/lang/String", "substring", "(I)Ljava/lang/String;", (6,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("substring beyond count must throw"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); for (begin, end) in [(3, 999), (4, 2), (-1, 3)] { - let result: Result> = jvm.invoke_virtual(&sub, "substring", "(II)Ljava/lang/String;", (begin, end)).await; + let result: Result> = jvm + .invoke_virtual(&sub, "java/lang/String", "substring", "(II)Ljava/lang/String;", (begin, end)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("substring({begin}, {end}) must throw"); }; @@ -1136,15 +1538,23 @@ async fn test_substring_preserves_unpaired_surrogate() -> Result<()> { jvm.store_array(&mut chars, 0, [0x61 as JavaChar, 0xd800, 0x62]).await?; let string = jvm.new_class("java/lang/String", "([C)V", (chars,)).await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&string, "substring", "(II)Ljava/lang/String;", (1, 2)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "substring", "(II)Ljava/lang/String;", (1, 2)) + .await?; - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&sub, "charAt", "(I)C", (0,)).await?, 0xd800); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&sub, "java/lang/String", "charAt", "(I)C", (0,)) + .await?, + 0xd800 + ); - let sub_chars: ClassInstanceRef> = jvm.invoke_virtual(&sub, "toCharArray", "()[C", ()).await?; + let sub_chars: ClassInstanceRef> = jvm.invoke_virtual(&sub, "java/lang/String", "toCharArray", "()[C", ()).await?; assert_eq!(jvm.load_array::(&sub_chars, 0, 1).await?, [0xd800]); let dst = jvm.instantiate_array("C", 1).await?; - let _: () = jvm.invoke_virtual(&sub, "getChars", "(II[CI)V", (0, 1, dst.clone(), 0)).await?; + let _: () = jvm + .invoke_virtual(&sub, "java/lang/String", "getChars", "(II[CI)V", (0, 1, dst.clone(), 0)) + .await?; assert_eq!(jvm.load_array::(&dst, 0, 1).await?, [0xd800]); Ok(()) @@ -1167,10 +1577,13 @@ async fn test_equals_uses_utf16_code_units() -> Result<()> { let third = jvm.new_class("java/lang/String", "([C)V", (third_chars,)).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&first, "equals", "(Ljava/lang/Object;)Z", (second,)) + !jvm.invoke_virtual::<_, bool>(&first, &first.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (second,)) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&first, &first.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (third,)) .await? ); - assert!(jvm.invoke_virtual::<_, bool>(&first, "equals", "(Ljava/lang/Object;)Z", (third,)).await?); Ok(()) } @@ -1203,7 +1616,7 @@ async fn test_init_with_string_shares_full_range_value() -> Result<()> { assert_eq!(jvm.get_field::(©, "offset", "I").await?, 0); assert_eq!(jvm.get_field::(©, "count", "I").await?, 5); assert!( - jvm.invoke_virtual::<_, bool>(©, "equals", "(Ljava/lang/Object;)Z", (original,)) + jvm.invoke_virtual::<_, bool>(©, ©.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (original,)) .await? ); @@ -1215,7 +1628,9 @@ async fn test_init_with_string_detaches_substring_with_exact_size_copy() -> Resu let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "HelloWorld").await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 5)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 5)) + .await?; let detached = jvm.new_class("java/lang/String", "(Ljava/lang/String;)V", (sub.clone(),)).await?; let sub_value: ClassInstanceRef> = jvm.get_field(&sub, "value", "[C").await?; @@ -1225,7 +1640,7 @@ async fn test_init_with_string_detaches_substring_with_exact_size_copy() -> Resu assert_eq!(jvm.get_field::(&detached, "offset", "I").await?, 0); assert_eq!(jvm.get_field::(&detached, "count", "I").await?, 3); assert!( - jvm.invoke_virtual::<_, bool>(&detached, "equals", "(Ljava/lang/Object;)Z", (sub,)) + jvm.invoke_virtual::<_, bool>(&detached, &detached.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (sub,)) .await? ); assert_eq!(JavaLangString::to_rust_string(&jvm, &detached).await?, "llo"); @@ -1240,7 +1655,13 @@ async fn test_init_with_string_buffer_is_independent_of_buffer() -> Result<()> { let string_buffer = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?; let hello = JavaLangString::from_rust_string(&jvm, "Hello").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&string_buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (hello,)) + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (hello,), + ) .await?; let string = jvm @@ -1250,9 +1671,23 @@ async fn test_init_with_string_buffer_is_independent_of_buffer() -> Result<()> { let world = JavaLangString::from_rust_string(&jvm, "World").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&string_buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (world,)) + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (world,), + ) + .await?; + let _: () = jvm + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "setCharAt", + "(IC)V", + (0, b'X' as JavaChar), + ) .await?; - let _: () = jvm.invoke_virtual(&string_buffer, "setCharAt", "(IC)V", (0, b'X' as JavaChar)).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &string).await?, "Hello"); @@ -1306,8 +1741,14 @@ async fn test_str_02_compare_to_uses_utf16_code_units_and_bridge_exceptions() -> let private_use = jvm.new_class("java/lang/String", "([C)V", (private_use_chars,)).await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&supplementary, "compareTo", "(Ljava/lang/String;)I", (private_use.clone(),)) - .await?, + jvm.invoke_virtual::<_, i32>( + &supplementary, + &supplementary.class_definition().name(), + "compareTo", + "(Ljava/lang/String;)I", + (private_use.clone(),) + ) + .await?, 0xd83d - 0xe000 ); @@ -1318,46 +1759,68 @@ async fn test_str_02_compare_to_uses_utf16_code_units_and_bridge_exceptions() -> jvm.store_array(&mut second_unpaired_chars, 0, [0xd801 as JavaChar]).await?; let second_unpaired = jvm.new_class("java/lang/String", "([C)V", (second_unpaired_chars,)).await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&first_unpaired, "compareTo", "(Ljava/lang/String;)I", (second_unpaired.clone(),),) - .await?, + jvm.invoke_virtual::<_, i32>( + &first_unpaired, + &first_unpaired.class_definition().name(), + "compareTo", + "(Ljava/lang/String;)I", + (second_unpaired.clone(),), + ) + .await?, -1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&first_unpaired, "compareTo", "(Ljava/lang/Object;)I", (second_unpaired,)) - .await?, + jvm.invoke_virtual::<_, i32>( + &first_unpaired, + &first_unpaired.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (second_unpaired,) + ) + .await?, -1 ); let a = JavaLangString::from_rust_string(&jvm, "a").await?; let ac = JavaLangString::from_rust_string(&jvm, "ac").await?; let az = JavaLangString::from_rust_string(&jvm, "az").await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&ac, "compareTo", "(Ljava/lang/String;)I", (az,)).await?, -23); assert_eq!( - jvm.invoke_virtual::<_, i32>(&a, "compareTo", "(Ljava/lang/String;)I", (ac.clone(),)) + jvm.invoke_virtual::<_, i32>(&ac, &ac.class_definition().name(), "compareTo", "(Ljava/lang/String;)I", (az,)) + .await?, + -23 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&a, &a.class_definition().name(), "compareTo", "(Ljava/lang/String;)I", (ac.clone(),)) .await?, -1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&ac, "compareTo", "(Ljava/lang/Object;)I", (ac.clone(),)) + jvm.invoke_virtual::<_, i32>(&ac, &ac.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (ac.clone(),)) .await?, 0 ); let null: ClassInstanceRef = None.into(); - let result: Result = jvm.invoke_virtual(&ac, "compareTo", "(Ljava/lang/String;)I", (null.clone(),)).await; + let result: Result = jvm + .invoke_virtual(&ac, &ac.class_definition().name(), "compareTo", "(Ljava/lang/String;)I", (null.clone(),)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("String.compareTo(String) must reject null"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let result: Result = jvm.invoke_virtual(&ac, "compareTo", "(Ljava/lang/Object;)I", (null,)).await; + let result: Result = jvm + .invoke_virtual(&ac, &ac.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (null,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("String.compareTo(Object) must reject null"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let result: Result = jvm.invoke_virtual(&ac, "compareTo", "(Ljava/lang/Object;)I", (object,)).await; + let result: Result = jvm + .invoke_virtual(&ac, &ac.class_definition().name(), "compareTo", "(Ljava/lang/Object;)I", (object,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("String.compareTo(Object) must reject non-String values"); }; @@ -1374,18 +1837,38 @@ async fn test_str_03_compare_to_ignore_case() -> Result<()> { let later = JavaLangString::from_rust_string(&jvm, "abd").await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&mixed, "compareToIgnoreCase", "(Ljava/lang/String;)I", (lower,)) - .await?, + jvm.invoke_virtual::<_, i32>( + &mixed, + &mixed.class_definition().name(), + "compareToIgnoreCase", + "(Ljava/lang/String;)I", + (lower,) + ) + .await?, 0 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&mixed, "compareToIgnoreCase", "(Ljava/lang/String;)I", (later,)) - .await?, + jvm.invoke_virtual::<_, i32>( + &mixed, + &mixed.class_definition().name(), + "compareToIgnoreCase", + "(Ljava/lang/String;)I", + (later,) + ) + .await?, -1 ); let null: ClassInstanceRef = None.into(); - let result: Result = jvm.invoke_virtual(&mixed, "compareToIgnoreCase", "(Ljava/lang/String;)I", (null,)).await; + let result: Result = jvm + .invoke_virtual( + &mixed, + &mixed.class_definition().name(), + "compareToIgnoreCase", + "(Ljava/lang/String;)I", + (null,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("compareToIgnoreCase must reject null"); }; @@ -1402,38 +1885,82 @@ async fn test_str_04_last_index_of_string_uses_utf16_indices() -> Result<()> { let empty = JavaLangString::from_rust_string(&jvm, "").await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "lastIndexOf", "(Ljava/lang/String;)I", (emoji.clone(),)) - .await?, + jvm.invoke_virtual::<_, i32>( + &string, + &string.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/String;)I", + (emoji.clone(),) + ) + .await?, 5 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "lastIndexOf", "(Ljava/lang/String;I)I", (emoji.clone(), 4)) - .await?, + jvm.invoke_virtual::<_, i32>( + &string, + &string.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/String;I)I", + (emoji.clone(), 4) + ) + .await?, 1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "lastIndexOf", "(Ljava/lang/String;I)I", (emoji, -1)) - .await?, + jvm.invoke_virtual::<_, i32>( + &string, + &string.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/String;I)I", + (emoji, -1) + ) + .await?, -1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "lastIndexOf", "(Ljava/lang/String;I)I", (empty.clone(), -1)) - .await?, + jvm.invoke_virtual::<_, i32>( + &string, + &string.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/String;I)I", + (empty.clone(), -1) + ) + .await?, -1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "lastIndexOf", "(Ljava/lang/String;I)I", (empty.clone(), 8)) - .await?, + jvm.invoke_virtual::<_, i32>( + &string, + &string.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/String;I)I", + (empty.clone(), 8) + ) + .await?, 8 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&string, "lastIndexOf", "(Ljava/lang/String;I)I", (empty, 9)) - .await?, + jvm.invoke_virtual::<_, i32>( + &string, + &string.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/String;I)I", + (empty, 9) + ) + .await?, 8 ); let null: ClassInstanceRef = None.into(); - let result: Result = jvm.invoke_virtual(&string, "lastIndexOf", "(Ljava/lang/String;)I", (null,)).await; + let result: Result = jvm + .invoke_virtual( + &string, + &string.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/String;)I", + (null,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("lastIndexOf(String) must reject null"); }; @@ -1494,20 +2021,44 @@ async fn test_str_06_region_matches_without_ignore_case() -> Result<()> { let same = JavaLangString::from_rust_string(&jvm, "x😀by").await?; assert!( - jvm.invoke_virtual::<_, bool>(&source, "regionMatches", "(ILjava/lang/String;II)Z", (1, same.clone(), 1, 3)) - .await? + jvm.invoke_virtual::<_, bool>( + &source, + &source.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (1, same.clone(), 1, 3) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&source, "regionMatches", "(ILjava/lang/String;II)Z", (-1, same.clone(), 1, 1)) - .await? + !jvm.invoke_virtual::<_, bool>( + &source, + &source.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (-1, same.clone(), 1, 1) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&source, "regionMatches", "(ILjava/lang/String;II)Z", (1, same.clone(), 1, 99)) - .await? + !jvm.invoke_virtual::<_, bool>( + &source, + &source.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (1, same.clone(), 1, 99) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&source, "regionMatches", "(ILjava/lang/String;II)Z", (1, same, 1, -1)) - .await? + jvm.invoke_virtual::<_, bool>( + &source, + &source.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (1, same, 1, -1) + ) + .await? ); let mut first_surrogate = jvm.instantiate_array("C", 1).await?; @@ -1517,13 +2068,25 @@ async fn test_str_06_region_matches_without_ignore_case() -> Result<()> { jvm.store_array(&mut second_surrogate, 0, [0xd801 as JavaChar]).await?; let second_surrogate = jvm.new_class("java/lang/String", "([C)V", (second_surrogate,)).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&first_surrogate, "regionMatches", "(ILjava/lang/String;II)Z", (0, second_surrogate, 0, 1),) - .await? + !jvm.invoke_virtual::<_, bool>( + &first_surrogate, + &first_surrogate.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (0, second_surrogate, 0, 1), + ) + .await? ); let null: ClassInstanceRef = None.into(); let result: Result = jvm - .invoke_virtual(&source, "regionMatches", "(ILjava/lang/String;II)Z", (0, null, 0, 0)) + .invoke_virtual( + &source, + &source.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (0, null, 0, 0), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("regionMatches must reject null"); @@ -1541,35 +2104,67 @@ async fn test_region_matches_non_positive_len() -> Result<()> { for len in [0, -1, i32::MIN] { assert!( - jvm.invoke_virtual::<_, bool>(&source, "regionMatches", "(ILjava/lang/String;II)Z", (1, other.clone(), 2, len)) - .await? + jvm.invoke_virtual::<_, bool>( + &source, + &source.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (1, other.clone(), 2, len) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&source, "regionMatches", "(ZILjava/lang/String;II)Z", (true, 1, other.clone(), 2, len)) - .await? + jvm.invoke_virtual::<_, bool>( + &source, + &source.class_definition().name(), + "regionMatches", + "(ZILjava/lang/String;II)Z", + (true, 1, other.clone(), 2, len) + ) + .await? ); } assert!( - jvm.invoke_virtual::<_, bool>(&source, "regionMatches", "(ILjava/lang/String;II)Z", (5, other.clone(), 5, 0)) - .await? + jvm.invoke_virtual::<_, bool>( + &source, + &source.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (5, other.clone(), 5, 0) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&source, "regionMatches", "(ILjava/lang/String;II)Z", (6, other.clone(), 0, 0)) - .await? + !jvm.invoke_virtual::<_, bool>( + &source, + &source.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (6, other.clone(), 0, 0) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&source, "regionMatches", "(ILjava/lang/String;II)Z", (0, other.clone(), 0, i32::MAX)) - .await? + !jvm.invoke_virtual::<_, bool>( + &source, + &source.class_definition().name(), + "regionMatches", + "(ILjava/lang/String;II)Z", + (0, other.clone(), 0, i32::MAX) + ) + .await? ); - let sub: ClassInstanceRef = jvm.invoke_virtual(&source, "substring", "(II)Ljava/lang/String;", (1, 3)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&source, &source.class_definition().name(), "substring", "(II)Ljava/lang/String;", (1, 3)) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&sub, "regionMatches", "(ILjava/lang/String;II)Z", (2, other, 0, -1)) + jvm.invoke_virtual::<_, bool>(&sub, "java/lang/String", "regionMatches", "(ILjava/lang/String;II)Z", (2, other, 0, -1)) .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&sub, "regionMatches", "(ILjava/lang/String;II)Z", (3, source, 0, 0)) + !jvm.invoke_virtual::<_, bool>(&sub, "java/lang/String", "regionMatches", "(ILjava/lang/String;II)Z", (3, source, 0, 0)) .await? ); @@ -1584,17 +2179,35 @@ async fn test_str_07_locale_case_overloads_and_float_formatting() -> Result<()> let mixed = JavaLangString::from_rust_string(&jvm, "AbC").await?; let lower: ClassInstanceRef = jvm - .invoke_virtual(&mixed, "toLowerCase", "(Ljava/util/Locale;)Ljava/lang/String;", (locale.clone(),)) + .invoke_virtual( + &mixed, + &mixed.class_definition().name(), + "toLowerCase", + "(Ljava/util/Locale;)Ljava/lang/String;", + (locale.clone(),), + ) .await?; let upper: ClassInstanceRef = jvm - .invoke_virtual(&mixed, "toUpperCase", "(Ljava/util/Locale;)Ljava/lang/String;", (locale,)) + .invoke_virtual( + &mixed, + &mixed.class_definition().name(), + "toUpperCase", + "(Ljava/util/Locale;)Ljava/lang/String;", + (locale,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &lower).await?, "abc"); assert_eq!(JavaLangString::to_rust_string(&jvm, &upper).await?, "ABC"); let null: ClassInstanceRef = None.into(); let result: Result> = jvm - .invoke_virtual(&mixed, "toLowerCase", "(Ljava/util/Locale;)Ljava/lang/String;", (null,)) + .invoke_virtual( + &mixed, + &mixed.class_definition().name(), + "toLowerCase", + "(Ljava/util/Locale;)Ljava/lang/String;", + (null,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("locale case conversion must reject null Locale"); @@ -1603,7 +2216,13 @@ async fn test_str_07_locale_case_overloads_and_float_formatting() -> Result<()> let null: ClassInstanceRef = None.into(); let result: Result> = jvm - .invoke_virtual(&mixed, "toUpperCase", "(Ljava/util/Locale;)Ljava/lang/String;", (null,)) + .invoke_virtual( + &mixed, + &mixed.class_definition().name(), + "toUpperCase", + "(Ljava/util/Locale;)Ljava/lang/String;", + (null,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("uppercase locale conversion must reject null Locale"); @@ -1635,42 +2254,64 @@ async fn test_empty_substring_behaves_like_empty_string() -> Result<()> { let parent = JavaLangString::from_rust_string(&jvm, "HelloWorld").await?; // offset ends exactly at value.length (offset 10, count 0) - let tail_empty: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(I)Ljava/lang/String;", (10,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&tail_empty, "length", "()I", ()).await?, 0); + let tail_empty: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(I)Ljava/lang/String;", (10,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&tail_empty, "java/lang/String", "length", "()I", ()).await?, + 0 + ); assert_eq!(JavaLangString::to_rust_string(&jvm, &tail_empty).await?, ""); - assert_eq!(jvm.invoke_virtual::<_, i32>(&tail_empty, "hashCode", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&tail_empty, "java/lang/String", "hashCode", "()I", ()) + .await?, + 0 + ); - let mid_empty: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (5, 5)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&mid_empty, "length", "()I", ()).await?, 0); + let mid_empty: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (5, 5)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&mid_empty, "java/lang/String", "length", "()I", ()).await?, + 0 + ); let empty = JavaLangString::from_rust_string(&jvm, "").await?; assert!( - jvm.invoke_virtual::<_, bool>(&mid_empty, "equals", "(Ljava/lang/Object;)Z", (empty.clone(),)) + jvm.invoke_virtual::<_, bool>(&mid_empty, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", (empty.clone(),)) .await? ); // searches on empty substring - assert_eq!(jvm.invoke_virtual::<_, i32>(&mid_empty, "indexOf", "(I)I", (b'l' as i32,)).await?, -1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&mid_empty, "java/lang/String", "indexOf", "(I)I", (b'l' as i32,)) + .await?, + -1 + ); let empty_pattern = JavaLangString::from_rust_string(&jvm, "").await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&mid_empty, "indexOf", "(Ljava/lang/String;)I", (empty_pattern,)) + jvm.invoke_virtual::<_, i32>(&mid_empty, "java/lang/String", "indexOf", "(Ljava/lang/String;)I", (empty_pattern,)) .await?, 0 ); // trim/toCharArray/charAt on empty substring - let trimmed: ClassInstanceRef = jvm.invoke_virtual(&mid_empty, "trim", "()Ljava/lang/String;", ()).await?; + let trimmed: ClassInstanceRef = jvm + .invoke_virtual(&mid_empty, "java/lang/String", "trim", "()Ljava/lang/String;", ()) + .await?; assert_eq!(mid_empty.identity(), trimmed.identity()); - let chars: ClassInstanceRef> = jvm.invoke_virtual(&mid_empty, "toCharArray", "()[C", ()).await?; + let chars: ClassInstanceRef> = jvm.invoke_virtual(&mid_empty, "java/lang/String", "toCharArray", "()[C", ()).await?; assert_eq!(jvm.array_length(&chars).await?, 0); - let result: Result = jvm.invoke_virtual(&mid_empty, "charAt", "(I)C", (0,)).await; + let result: Result = jvm.invoke_virtual(&mid_empty, "java/lang/String", "charAt", "(I)C", (0,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("charAt(0) on empty substring must throw"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); // intern of empty substring meets the pooled empty string - let interned: ClassInstanceRef = jvm.invoke_virtual(&mid_empty, "intern", "()Ljava/lang/String;", ()).await?; + let interned: ClassInstanceRef = jvm + .invoke_virtual(&mid_empty, "java/lang/String", "intern", "()Ljava/lang/String;", ()) + .await?; let pooled = jvm.intern_string("").await?; assert_eq!(interned.identity(), ClassInstanceRef::::from(pooled).identity()); @@ -1682,11 +2323,13 @@ async fn test_trim_to_empty_on_all_whitespace_substring() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "ab cd").await?; - let blank: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 5)).await?; + let blank: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 5)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &blank).await?, " "); - let trimmed: ClassInstanceRef = jvm.invoke_virtual(&blank, "trim", "()Ljava/lang/String;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&trimmed, "length", "()I", ()).await?, 0); + let trimmed: ClassInstanceRef = jvm.invoke_virtual(&blank, "java/lang/String", "trim", "()Ljava/lang/String;", ()).await?; + assert_eq!(jvm.invoke_virtual::<_, i32>(&trimmed, "java/lang/String", "length", "()I", ()).await?, 0); assert_eq!(JavaLangString::to_rust_string(&jvm, &trimmed).await?, ""); Ok(()) @@ -1697,15 +2340,25 @@ async fn test_last_index_of_from_beyond_count_on_substring() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let sub: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 7)) + .await?; // fromIndex beyond count is clamped and must not see parent's 'y' - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub, "lastIndexOf", "(II)I", (b'o' as i32, 99)).await?, 4); - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub, "lastIndexOf", "(II)I", (b'y' as i32, 99)).await?, -1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "lastIndexOf", "(II)I", (b'o' as i32, 99)) + .await?, + 4 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "lastIndexOf", "(II)I", (b'y' as i32, 99)) + .await?, + -1 + ); let pattern = JavaLangString::from_rust_string(&jvm, "He").await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&sub, "lastIndexOf", "(Ljava/lang/String;I)I", (pattern, 99)) + jvm.invoke_virtual::<_, i32>(&sub, "java/lang/String", "lastIndexOf", "(Ljava/lang/String;I)I", (pattern, 99)) .await?, 0 ); @@ -1754,13 +2407,17 @@ async fn test_corrupted_length_fields_raise_java_exceptions() -> Result<()> { let mut string = JavaLangString::from_rust_string(&jvm, "Hello").await?; jvm.put_field(&mut string, field, "I", -1i32).await?; - let result: Result = jvm.invoke_virtual(&string, "hashCode", "()I", ()).await; + let result: Result = jvm + .invoke_virtual(&string, &string.class_definition().name(), "hashCode", "()I", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("a negative {field} must not be read as a length"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let result: Result = jvm.invoke_virtual(&string, "charAt", "(I)C", (0i32,)).await; + let result: Result = jvm + .invoke_virtual(&string, &string.class_definition().name(), "charAt", "(I)C", (0i32,)) + .await; assert!(matches!(result, Err(JavaError::JavaException(_)))); let result = JavaLangString::to_rust_string(&jvm, &string).await; @@ -1769,7 +2426,9 @@ async fn test_corrupted_length_fields_raise_java_exceptions() -> Result<()> { let mut string = JavaLangString::from_rust_string(&jvm, "Hello").await?; jvm.put_field(&mut string, "count", "I", i32::MAX).await?; - let result: Result = jvm.invoke_virtual(&string, "hashCode", "()I", ()).await; + let result: Result = jvm + .invoke_virtual(&string, &string.class_definition().name(), "hashCode", "()I", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("a count past the backing array must not be read"); }; diff --git a/java_runtime/tests/classes/java/lang/test_string_buffer.rs b/java_runtime/tests/classes/java/lang/test_string_buffer.rs index 64e7d8fa..5435eee6 100644 --- a/java_runtime/tests/classes/java/lang/test_string_buffer.rs +++ b/java_runtime/tests/classes/java/lang/test_string_buffer.rs @@ -24,12 +24,20 @@ async fn string_buffer_char_sequence_sub_sequence_is_a_synchronized_snapshot() - let jvm = test_jvm().await?; let source = JavaLangString::from_rust_string(&jvm, "Hello").await?; let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (source,)).await?.into(); - let subsequence: ClassInstanceRef = jvm.invoke_virtual(&buffer, "subSequence", "(II)Ljava/lang/CharSequence;", (1, 4)).await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&subsequence, "toString", "()Ljava/lang/String;", ()).await?; + let subsequence: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "subSequence", "(II)Ljava/lang/CharSequence;", (1, 4)) + .await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&subsequence, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "ell"); - let _: () = jvm.invoke_virtual(&buffer, "setCharAt", "(IC)V", (2, 'X' as JavaChar)).await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&subsequence, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "setCharAt", "(IC)V", (2, 'X' as JavaChar)) + .await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&subsequence, "java/lang/Object", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "ell"); Ok(()) @@ -43,34 +51,92 @@ async fn test_string_buffer() -> Result<()> { let string = JavaLangString::from_rust_string(&jvm, "Hello, ").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&string_buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (string,)) + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (string,), + ) .await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&string_buffer, "append", "(I)Ljava/lang/StringBuffer;", (42,)).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&string_buffer, "append", "(Z)Ljava/lang/StringBuffer;", (true,)) + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "append", + "(I)Ljava/lang/StringBuffer;", + (42,), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&string_buffer, "append", "(C)Ljava/lang/StringBuffer;", (b'H' as JavaChar,)) + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "append", + "(Z)Ljava/lang/StringBuffer;", + (true,), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&string_buffer, "append", "(J)Ljava/lang/StringBuffer;", (42i64,)) + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "append", + "(C)Ljava/lang/StringBuffer;", + (b'H' as JavaChar,), + ) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "append", + "(J)Ljava/lang/StringBuffer;", + (42i64,), + ) .await?; - let length: i32 = jvm.invoke_virtual(&string_buffer, "length", "()I", ()).await?; + let length: i32 = jvm + .invoke_virtual(&string_buffer, &string_buffer.class_definition().name(), "length", "()I", ()) + .await?; assert_eq!(length, 16); - let char: JavaChar = jvm.invoke_virtual(&string_buffer, "charAt", "(I)C", (7,)).await?; + let char: JavaChar = jvm + .invoke_virtual(&string_buffer, &string_buffer.class_definition().name(), "charAt", "(I)C", (7,)) + .await?; assert_eq!(char, '4' as JavaChar); - let result = jvm.invoke_virtual(&string_buffer, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; let result = JavaLangString::to_rust_string(&jvm, &result).await?; assert_eq!("Hello, 42trueH42", result); let _: ClassInstanceRef = jvm - .invoke_virtual(&string_buffer, "delete", "(II)Ljava/lang/StringBuffer;", (5, 7)) + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "delete", + "(II)Ljava/lang/StringBuffer;", + (5, 7), + ) + .await?; + let result = jvm + .invoke_virtual( + &string_buffer, + &string_buffer.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) .await?; - let result = jvm.invoke_virtual(&string_buffer, "toString", "()Ljava/lang/String;", ()).await?; let result = JavaLangString::to_rust_string(&jvm, &result).await?; assert_eq!("Hello42trueH42", result); @@ -81,12 +147,24 @@ async fn test_string_buffer() -> Result<()> { async fn test_sb_01_constructors_capacity_and_exceptions() -> Result<()> { let jvm = test_jvm().await?; let empty = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&empty, "capacity", "()I", ()).await?, 16); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&empty, &empty.class_definition().name(), "capacity", "()I", ()) + .await?, + 16 + ); let source = JavaLangString::from_rust_string(&jvm, "abc").await?; let from_string = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (source,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&from_string, "capacity", "()I", ()).await?, 19); - assert_eq!(jvm.invoke_virtual::<_, i32>(&from_string, "length", "()I", ()).await?, 3); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&from_string, &from_string.class_definition().name(), "capacity", "()I", ()) + .await?, + 19 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&from_string, &from_string.class_definition().name(), "length", "()I", ()) + .await?, + 3 + ); let result = jvm.new_class("java/lang/StringBuffer", "(I)V", (-1,)).await; let Err(JavaError::JavaException(exception)) = result else { @@ -109,12 +187,30 @@ async fn test_sb_02_capacity_and_ensure_capacity_growth() -> Result<()> { let jvm = test_jvm().await?; let buffer = jvm.new_class("java/lang/StringBuffer", "(I)V", (2,)).await?; - let _: () = jvm.invoke_virtual(&buffer, "ensureCapacity", "(I)V", (3,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, 6); - let _: () = jvm.invoke_virtual(&buffer, "ensureCapacity", "(I)V", (20,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, 20); - let _: () = jvm.invoke_virtual(&buffer, "ensureCapacity", "(I)V", (-1,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, 20); + let _: () = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "ensureCapacity", "(I)V", (3,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + 6 + ); + let _: () = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "ensureCapacity", "(I)V", (20,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + 20 + ); + let _: () = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "ensureCapacity", "(I)V", (-1,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + 20 + ); Ok(()) } @@ -124,13 +220,31 @@ async fn test_sb_03_length_char_access_and_synchronized_flags() -> Result<()> { let jvm = test_jvm().await?; let buffer = jvm.new_class("java/lang/StringBuffer", "(I)V", (1,)).await?; - let _: () = jvm.invoke_virtual(&buffer, "setLength", "(I)V", (3,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, 3); - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&buffer, "charAt", "(I)C", (1,)).await?, 0); - let _: () = jvm.invoke_virtual(&buffer, "setCharAt", "(IC)V", (1, 'x' as JavaChar)).await?; - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&buffer, "charAt", "(I)C", (1,)).await?, 'x' as JavaChar); - let _: () = jvm.invoke_virtual(&buffer, "setLength", "(I)V", (1,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, 1); + let _: () = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "setLength", "(I)V", (3,)).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + 3 + ); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&buffer, "java/lang/StringBuffer", "charAt", "(I)C", (1,)) + .await?, + 0 + ); + let _: () = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "setCharAt", "(IC)V", (1, 'x' as JavaChar)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&buffer, "java/lang/StringBuffer", "charAt", "(I)C", (1,)) + .await?, + 'x' as JavaChar + ); + let _: () = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "setLength", "(I)V", (1,)).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + 1 + ); for (name, descriptor) in [ ("append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"), @@ -192,32 +306,46 @@ async fn test_sb_03_length_char_access_and_synchronized_flags() -> Result<()> { } for index in [-1, 1] { - let result: Result = jvm.invoke_virtual(&buffer, "charAt", "(I)C", (index,)).await; + let result: Result = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "charAt", "(I)C", (index,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("charAt must reject index {index}"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let result: Result<()> = jvm.invoke_virtual(&buffer, "setCharAt", "(IC)V", (index, 'z' as JavaChar)).await; + let result: Result<()> = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "setCharAt", "(IC)V", (index, 'z' as JavaChar)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("setCharAt must reject index {index}"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); } - let before_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let before_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; let before_text = JavaLangString::to_rust_string(&jvm, &before_text).await?; - let before_length: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; - let before_capacity: i32 = jvm.invoke_virtual(&buffer, "capacity", "()I", ()).await?; - let result: Result<()> = jvm.invoke_virtual(&buffer, "setLength", "(I)V", (-1,)).await; + let before_length: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; + let before_capacity: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()).await?; + let result: Result<()> = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "setLength", "(I)V", (-1,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("setLength must reject a negative length"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, before_text); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, before_length); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, before_capacity); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + before_length + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + before_capacity + ); Ok(()) } @@ -231,7 +359,7 @@ async fn test_sb_04_get_chars_checks_source_and_destination_ranges() -> Result<( jvm.store_array(&mut destination, 0, ['_' as JavaChar; 5]).await?; let _: () = jvm - .invoke_virtual(&buffer, "getChars", "(II[CI)V", (1, 3, destination.clone(), 2)) + .invoke_virtual(&buffer, "java/lang/StringBuffer", "getChars", "(II[CI)V", (1, 3, destination.clone(), 2)) .await?; assert_eq!( jvm.load_array::(&destination, 0, 5).await?, @@ -240,7 +368,13 @@ async fn test_sb_04_get_chars_checks_source_and_destination_ranges() -> Result<( for (start, end) in [(-1, 1), (2, 1), (0, 5)] { let result: Result<()> = jvm - .invoke_virtual(&buffer, "getChars", "(II[CI)V", (start, end, destination.clone(), 0)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "getChars", + "(II[CI)V", + (start, end, destination.clone(), 0), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("getChars must reject source range ({start}, {end})"); @@ -250,7 +384,13 @@ async fn test_sb_04_get_chars_checks_source_and_destination_ranges() -> Result<( for destination_offset in [-1, 4] { let result: Result<()> = jvm - .invoke_virtual(&buffer, "getChars", "(II[CI)V", (0, 2, destination.clone(), destination_offset)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "getChars", + "(II[CI)V", + (0, 2, destination.clone(), destination_offset), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("getChars must reject destination offset {destination_offset}"); @@ -259,7 +399,9 @@ async fn test_sb_04_get_chars_checks_source_and_destination_ranges() -> Result<( } let null: ClassInstanceRef> = None.into(); - let result: Result<()> = jvm.invoke_virtual(&buffer, "getChars", "(II[CI)V", (0, 1, null, 0)).await; + let result: Result<()> = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "getChars", "(II[CI)V", (0, 1, null, 0)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("getChars must reject a null destination"); }; @@ -275,14 +417,24 @@ async fn test_sb_05_append_float_double_and_char_array() -> Result<()> { let mut chars = jvm.instantiate_array("C", 2).await?; jvm.store_array(&mut chars, 0, ['x' as JavaChar, 'y' as JavaChar]).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "append", "(F)Ljava/lang/StringBuffer;", (1.0f32,)).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "append", "(D)Ljava/lang/StringBuffer;", (-0.0f64,)).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "append", "([C)Ljava/lang/StringBuffer;", (chars,)).await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "append", "(F)Ljava/lang/StringBuffer;", (1.0f32,)) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "append", "(D)Ljava/lang/StringBuffer;", (-0.0f64,)) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "append", "([C)Ljava/lang/StringBuffer;", (chars,)) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "1.0-0.0xy"); let null: ClassInstanceRef> = None.into(); - let result: Result> = jvm.invoke_virtual(&buffer, "append", "([C)Ljava/lang/StringBuffer;", (null,)).await; + let result: Result> = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "append", "([C)Ljava/lang/StringBuffer;", (null,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("append(char[]) must reject null"); }; @@ -290,13 +442,27 @@ async fn test_sb_05_append_float_double_and_char_array() -> Result<()> { let null_string: ClassInstanceRef = None.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (null_string,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (null_string,), + ) .await?; let null_object: ClassInstanceRef = None.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/Object;)Ljava/lang/StringBuffer;", (null_object,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/Object;)Ljava/lang/StringBuffer;", + (null_object,), + ) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) .await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "1.0-0.0xynullnull"); Ok(()) @@ -313,36 +479,69 @@ async fn test_sb_06_insert_overloads_and_boundaries() -> Result<()> { jvm.store_array(&mut chars, 0, ['C' as JavaChar]).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (0, text)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (0, text), + ) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/Object;)Ljava/lang/StringBuffer;", + (1, object), + ) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "insert", "(IZ)Ljava/lang/StringBuffer;", (2, true)) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(IC)Ljava/lang/StringBuffer;", + (6, '!' as JavaChar), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(ILjava/lang/Object;)Ljava/lang/StringBuffer;", (1, object)) + .invoke_virtual(&buffer, "java/lang/StringBuffer", "insert", "(II)Ljava/lang/StringBuffer;", (7, 12)) .await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "insert", "(IZ)Ljava/lang/StringBuffer;", (2, true)).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(IC)Ljava/lang/StringBuffer;", (6, '!' as JavaChar)) + .invoke_virtual(&buffer, "java/lang/StringBuffer", "insert", "(IJ)Ljava/lang/StringBuffer;", (9, 34i64)) .await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "insert", "(II)Ljava/lang/StringBuffer;", (7, 12)).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "insert", "(IJ)Ljava/lang/StringBuffer;", (9, 34i64)).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(IF)Ljava/lang/StringBuffer;", (11, 1.0f32)) + .invoke_virtual(&buffer, "java/lang/StringBuffer", "insert", "(IF)Ljava/lang/StringBuffer;", (11, 1.0f32)) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(ID)Ljava/lang/StringBuffer;", (14, 2.0f64)) + .invoke_virtual(&buffer, "java/lang/StringBuffer", "insert", "(ID)Ljava/lang/StringBuffer;", (14, 2.0f64)) .await?; - let length: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; + let length: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(I[C)Ljava/lang/StringBuffer;", (length, chars)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(I[C)Ljava/lang/StringBuffer;", + (length, chars), + ) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) .await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "SOtrue!12341.02.0abC"); let sequence = JavaLangString::from_rust_string(&jvm, "string").await?; let sequence: ClassInstanceRef = sequence.into(); - let length: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; + let length: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; let _: ClassInstanceRef = jvm .invoke_virtual( &buffer, + "java/lang/StringBuffer", "insert", "(ILjava/lang/CharSequence;)Ljava/lang/StringBuffer;", (length, sequence), @@ -351,66 +550,112 @@ async fn test_sb_06_insert_overloads_and_boundaries() -> Result<()> { let sequence = JavaLangString::from_rust_string(&jvm, "buffer").await?; let sequence = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (sequence,)).await?; let sequence: ClassInstanceRef = sequence.into(); - let length: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; + let length: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; let _: ClassInstanceRef = jvm .invoke_virtual( &buffer, + "java/lang/StringBuffer", "insert", "(ILjava/lang/CharSequence;)Ljava/lang/StringBuffer;", (length, sequence), ) .await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "SOtrue!12341.02.0abCstringbuffer"); let sequence: ClassInstanceRef = None.into(); - let length: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; + let length: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; let _: ClassInstanceRef = jvm .invoke_virtual( &buffer, + "java/lang/StringBuffer", "insert", "(ILjava/lang/CharSequence;)Ljava/lang/StringBuffer;", (length, sequence), ) .await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "SOtrue!12341.02.0abCstringbuffernull"); let null_string: ClassInstanceRef = None.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (0, null_string)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (0, null_string), + ) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "substring", "(II)Ljava/lang/String;", (0, 4)) .await?; - let text = jvm.invoke_virtual(&buffer, "substring", "(II)Ljava/lang/String;", (0, 4)).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "null"); let null_object: ClassInstanceRef = None.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(ILjava/lang/Object;)Ljava/lang/StringBuffer;", (4, null_object)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/Object;)Ljava/lang/StringBuffer;", + (4, null_object), + ) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "substring", "(II)Ljava/lang/String;", (0, 8)) .await?; - let text = jvm.invoke_virtual(&buffer, "substring", "(II)Ljava/lang/String;", (0, 8)).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "nullnull"); - let before_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let before_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; let before_text = JavaLangString::to_rust_string(&jvm, &before_text).await?; - let before_length: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; - let before_capacity: i32 = jvm.invoke_virtual(&buffer, "capacity", "()I", ()).await?; + let before_length: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; + let before_capacity: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()).await?; for offset in [-1, 100] { let result: Result> = jvm - .invoke_virtual(&buffer, "insert", "(IC)Ljava/lang/StringBuffer;", (offset, 'x' as JavaChar)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(IC)Ljava/lang/StringBuffer;", + (offset, 'x' as JavaChar), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("insert must reject offset {offset}"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let after_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let after_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &after_text).await?, before_text); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, before_length); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, before_capacity); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + before_length + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + before_capacity + ); } let null_chars: ClassInstanceRef> = None.into(); let result: Result> = jvm - .invoke_virtual(&buffer, "insert", "(I[C)Ljava/lang/StringBuffer;", (0, null_chars)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(I[C)Ljava/lang/StringBuffer;", + (0, null_chars), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("insert(char[]) must reject null"); @@ -420,16 +665,32 @@ async fn test_sb_06_insert_overloads_and_boundaries() -> Result<()> { for offset in [-1, before_length + 1] { let null_chars: ClassInstanceRef> = None.into(); let result: Result> = jvm - .invoke_virtual(&buffer, "insert", "(I[C)Ljava/lang/StringBuffer;", (offset, null_chars)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(I[C)Ljava/lang/StringBuffer;", + (offset, null_chars), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("insert(char[]) must validate invalid offset {offset} before null"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let after_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let after_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &after_text).await?, before_text); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, before_length); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, before_capacity); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + before_length + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + before_capacity + ); } Ok(()) @@ -443,9 +704,13 @@ async fn test_sb_07_reverse_uses_raw_utf16_code_units() -> Result<()> { let string = jvm.new_class("java/lang/String", "([C)V", (chars,)).await?; let buffer = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (string,)).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "reverse", "()Ljava/lang/StringBuffer;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "reverse", "()Ljava/lang/StringBuffer;", ()) + .await?; let reversed = jvm.instantiate_array("C", 3).await?; - let _: () = jvm.invoke_virtual(&buffer, "getChars", "(II[CI)V", (0, 3, reversed.clone(), 0)).await?; + let _: () = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "getChars", "(II[CI)V", (0, 3, reversed.clone(), 0)) + .await?; assert_eq!(jvm.load_array::(&reversed, 0, 3).await?, [0xdc00, 'a' as JavaChar, 0xd800]); Ok(()) @@ -456,41 +721,75 @@ async fn test_sb_08_delete_and_delete_char_at_ranges() -> Result<()> { let jvm = test_jvm().await?; let source = JavaLangString::from_rust_string(&jvm, "abcdef").await?; let buffer = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (source,)).await?; - let initial_capacity: i32 = jvm.invoke_virtual(&buffer, "capacity", "()I", ()).await?; + let initial_capacity: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "delete", "(II)Ljava/lang/StringBuffer;", (2, 100)).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "deleteCharAt", "(I)Ljava/lang/StringBuffer;", (1,)).await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "delete", "(II)Ljava/lang/StringBuffer;", (2, 100)) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "deleteCharAt", "(I)Ljava/lang/StringBuffer;", (1,)) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "a"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, initial_capacity); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + initial_capacity + ); - let before_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let before_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; let before_text = JavaLangString::to_rust_string(&jvm, &before_text).await?; - let before_length: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; + let before_length: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; for (start, end) in [(-1, 1), (2, 1), (2, 2)] { - let result: Result> = - jvm.invoke_virtual(&buffer, "delete", "(II)Ljava/lang/StringBuffer;", (start, end)).await; + let result: Result> = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "delete", "(II)Ljava/lang/StringBuffer;", (start, end)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("delete must reject ({start}, {end})"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let after_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let after_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &after_text).await?, before_text); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, before_length); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, initial_capacity); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + before_length + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + initial_capacity + ); } for index in [-1, 1] { - let result: Result> = - jvm.invoke_virtual(&buffer, "deleteCharAt", "(I)Ljava/lang/StringBuffer;", (index,)).await; + let result: Result> = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "deleteCharAt", "(I)Ljava/lang/StringBuffer;", (index,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("deleteCharAt must reject {index}"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let after_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let after_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &after_text).await?, before_text); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, before_length); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, initial_capacity); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + before_length + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + initial_capacity + ); } Ok(()) @@ -502,14 +801,19 @@ async fn test_sb_09_substring_uses_logical_count() -> Result<()> { let source = JavaLangString::from_rust_string(&jvm, "abcdef").await?; let buffer = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (source,)).await?; - let tail = jvm.invoke_virtual(&buffer, "substring", "(I)Ljava/lang/String;", (2,)).await?; - let middle = jvm.invoke_virtual(&buffer, "substring", "(II)Ljava/lang/String;", (1, 4)).await?; + let tail = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "substring", "(I)Ljava/lang/String;", (2,)) + .await?; + let middle = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "substring", "(II)Ljava/lang/String;", (1, 4)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &tail).await?, "cdef"); assert_eq!(JavaLangString::to_rust_string(&jvm, &middle).await?, "bcd"); for (start, end) in [(-1, 1), (3, 2), (0, 7)] { - let result: Result> = - jvm.invoke_virtual(&buffer, "substring", "(II)Ljava/lang/String;", (start, end)).await; + let result: Result> = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "substring", "(II)Ljava/lang/String;", (start, end)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("substring must reject ({start}, {end})"); }; @@ -529,23 +833,29 @@ async fn test_sb_10_replace_clamps_end_and_checks_ranges() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &buffer, + "java/lang/StringBuffer", "replace", "(IILjava/lang/String;)Ljava/lang/StringBuffer;", (2, 100, replacement), ) .await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "abXY"); - let before_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let before_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; let before_text = JavaLangString::to_rust_string(&jvm, &before_text).await?; - let before_length: i32 = jvm.invoke_virtual(&buffer, "length", "()I", ()).await?; - let before_capacity: i32 = jvm.invoke_virtual(&buffer, "capacity", "()I", ()).await?; + let before_length: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "length", "()I", ()).await?; + let before_capacity: i32 = jvm.invoke_virtual(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()).await?; let replacement = JavaLangString::from_rust_string(&jvm, "z").await?; for (start, end) in [(-1, 1), (3, 2), (5, 5)] { let result: Result> = jvm .invoke_virtual( &buffer, + "java/lang/StringBuffer", "replace", "(IILjava/lang/String;)Ljava/lang/StringBuffer;", (start, end, replacement.clone()), @@ -555,37 +865,79 @@ async fn test_sb_10_replace_clamps_end_and_checks_ranges() -> Result<()> { panic!("replace must reject ({start}, {end})"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let after_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let after_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &after_text).await?, before_text); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, before_length); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, before_capacity); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + before_length + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + before_capacity + ); } let null: ClassInstanceRef = None.into(); let result: Result> = jvm - .invoke_virtual(&buffer, "replace", "(IILjava/lang/String;)Ljava/lang/StringBuffer;", (0, 1, null)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "replace", + "(IILjava/lang/String;)Ljava/lang/StringBuffer;", + (0, 1, null), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("replace must reject null"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let after_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let after_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &after_text).await?, before_text); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, before_length); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, before_capacity); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + before_length + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + before_capacity + ); let null: ClassInstanceRef = None.into(); let result: Result> = jvm - .invoke_virtual(&buffer, "replace", "(IILjava/lang/String;)Ljava/lang/StringBuffer;", (-1, 1, null)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "replace", + "(IILjava/lang/String;)Ljava/lang/StringBuffer;", + (-1, 1, null), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("replace must validate its range before dereferencing the replacement"); }; assert!(jvm.is_instance(&*exception, "java/lang/StringIndexOutOfBoundsException")); - let after_text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let after_text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &after_text).await?, before_text); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, before_length); - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "capacity", "()I", ()).await?, before_capacity); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + before_length + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "capacity", "()I", ()) + .await?, + before_capacity + ); Ok(()) } @@ -595,31 +947,73 @@ async fn test_sb_11_string_arguments_backed_by_shared_substring() -> Result<()> let jvm = test_jvm().await?; let hello_parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let hello: ClassInstanceRef = - jvm.invoke_virtual(&hello_parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let hello: ClassInstanceRef = jvm + .invoke_virtual( + &hello_parent, + &hello_parent.class_definition().name(), + "substring", + "(II)Ljava/lang/String;", + (2, 7), + ) + .await?; let world_parent = JavaLangString::from_rust_string(&jvm, "zzWorldzz").await?; - let world: ClassInstanceRef = - jvm.invoke_virtual(&world_parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let world: ClassInstanceRef = jvm + .invoke_virtual( + &world_parent, + &world_parent.class_definition().name(), + "substring", + "(II)Ljava/lang/String;", + (2, 7), + ) + .await?; let buffer = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (hello.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&buffer, "length", "()I", ()).await?, 5); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&buffer, "java/lang/StringBuffer", "length", "()I", ()) + .await?, + 5 + ); let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (hello.clone(),)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (hello.clone(),), + ) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) .await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "HelloHello"); let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (0, world.clone())) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (0, world.clone()), + ) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) .await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "WorldHelloHello"); let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "replace", "(IILjava/lang/String;)Ljava/lang/StringBuffer;", (5, 10, world)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "replace", + "(IILjava/lang/String;)Ljava/lang/StringBuffer;", + (5, 10, world), + ) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) .await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "WorldWorldHello"); Ok(()) @@ -632,10 +1026,18 @@ async fn test_sb_12_to_string_snapshot_is_exact_size_and_immutable() -> Result<( let buffer = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?; let hello = JavaLangString::from_rust_string(&jvm, "Hello").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (hello,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (hello,), + ) .await?; - let string = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let string = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &string).await?, "Hello"); let buffer_value: ClassInstanceRef> = jvm.get_field(&buffer, "value", "[C").await?; @@ -647,9 +1049,17 @@ async fn test_sb_12_to_string_snapshot_is_exact_size_and_immutable() -> Result<( let world = JavaLangString::from_rust_string(&jvm, "World").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (world,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (world,), + ) + .await?; + let _: () = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "setCharAt", "(IC)V", (0, b'X' as JavaChar)) .await?; - let _: () = jvm.invoke_virtual(&buffer, "setCharAt", "(IC)V", (0, b'X' as JavaChar)).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &string).await?, "Hello"); @@ -661,26 +1071,49 @@ async fn test_sb_13_insert_substring_then_reverse_and_delete() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let sub: ClassInstanceRef = - jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 7)) + .await?; let buffer = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?; let ab = JavaLangString::from_rust_string(&jvm, "ab").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (ab,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (ab,), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "insert", "(ILjava/lang/String;)Ljava/lang/StringBuffer;", (1, sub.clone())) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "insert", + "(ILjava/lang/String;)Ljava/lang/StringBuffer;", + (1, sub.clone()), + ) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) .await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "aHellob"); - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "reverse", "()Ljava/lang/StringBuffer;", ()).await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "reverse", "()Ljava/lang/StringBuffer;", ()) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "bolleHa"); - let _: ClassInstanceRef = jvm.invoke_virtual(&buffer, "delete", "(II)Ljava/lang/StringBuffer;", (1, 5)).await?; - let text = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "delete", "(II)Ljava/lang/StringBuffer;", (1, 5)) + .await?; + let text = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "bHa"); // the buffer mutations must never leak into the shared parent @@ -697,17 +1130,29 @@ async fn test_sb_14_append_surrogate_substring_preserves_code_unit() -> Result<( let mut chars = jvm.instantiate_array("C", 3).await?; jvm.store_array(&mut chars, 0, [0x61 as JavaChar, 0xd800, 0x62]).await?; let string = jvm.new_class("java/lang/String", "([C)V", (chars,)).await?; - let sub: ClassInstanceRef = - jvm.invoke_virtual(&string, "substring", "(II)Ljava/lang/String;", (1, 2)).await?; + let sub: ClassInstanceRef = jvm + .invoke_virtual(&string, &string.class_definition().name(), "substring", "(II)Ljava/lang/String;", (1, 2)) + .await?; let buffer = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&buffer, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;", (sub,)) + .invoke_virtual( + &buffer, + "java/lang/StringBuffer", + "append", + "(Ljava/lang/String;)Ljava/lang/StringBuffer;", + (sub,), + ) .await?; - let text: ClassInstanceRef = - jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&text, "length", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&text, "charAt", "(I)C", (0,)).await?, 0xd800); + let text: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; + assert_eq!(jvm.invoke_virtual::<_, i32>(&text, "java/lang/String", "length", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&text, "java/lang/String", "charAt", "(I)C", (0,)) + .await?, + 0xd800 + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/lang/test_string_builder.rs b/java_runtime/tests/classes/java/lang/test_string_builder.rs index 32ebf22d..41b3829b 100644 --- a/java_runtime/tests/classes/java/lang/test_string_builder.rs +++ b/java_runtime/tests/classes/java/lang/test_string_builder.rs @@ -140,17 +140,47 @@ async fn string_builder_mutation_queries_and_appendable_bridge_use_utf16() -> Re let text = JavaLangString::from_utf16(&jvm, vec!['A' as JavaChar, 0xd83d, 0xde00]).await?; let text: ClassInstanceRef = text.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(&builder, "append", "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;", (text,)) + .invoke_virtual( + &builder, + &builder.class_definition().name(), + "append", + "(Ljava/lang/CharSequence;)Ljava/lang/Appendable;", + (text,), + ) .await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&builder, "append", "(I)Ljava/lang/StringBuilder;", (42,)).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&builder, "insert", "(IC)Ljava/lang/StringBuilder;", (1, '-' as JavaChar)) + .invoke_virtual( + &builder, + &builder.class_definition().name(), + "append", + "(I)Ljava/lang/StringBuilder;", + (42,), + ) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &builder, + &builder.class_definition().name(), + "insert", + "(IC)Ljava/lang/StringBuilder;", + (1, '-' as JavaChar), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&builder, "length", "()I", ()).await?, 6); - assert_eq!(jvm.invoke_virtual::<_, i32>(&builder, "codePointAt", "(I)I", (2,)).await?, 0x1f600); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&builder, &builder.class_definition().name(), "length", "()I", ()) + .await?, + 6 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&builder, &builder.class_definition().name(), "codePointAt", "(I)I", (2,)) + .await?, + 0x1f600 + ); - let result = jvm.invoke_virtual(&builder, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&builder, &builder.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!( JavaLangString::to_utf16(&jvm, &result).await?, vec![0x41, 0x2d, 0xd83d, 0xde00, 0x34, 0x32] diff --git a/java_runtime/tests/classes/java/lang/test_system.rs b/java_runtime/tests/classes/java/lang/test_system.rs index 02c71100..4ad10509 100644 --- a/java_runtime/tests/classes/java/lang/test_system.rs +++ b/java_runtime/tests/classes/java/lang/test_system.rs @@ -28,7 +28,7 @@ async fn test_system_time_yield_and_exit_runtime_contract() -> Result<()> { assert_eq!(runtime.exit_status(), Some(i32::MIN)); let runtime_instance: ClassInstanceRef = jvm.invoke_static("java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", ()).await?; - let _: () = jvm.invoke_virtual(&runtime_instance, "exit", "(I)V", (23,)).await?; + let _: () = jvm.invoke_virtual(&runtime_instance, "java/lang/Runtime", "exit", "(I)V", (23,)).await?; assert_eq!(runtime.exit_status(), Some(23)); Ok(()) @@ -68,7 +68,10 @@ async fn sys_01_to_06_descriptors_streams_properties_and_identity_hash() -> Resu let stdin: ClassInstanceRef = jvm.get_static_field("java/lang/System", "in", "Ljava/io/InputStream;").await?; assert!(!stdin.is_null()); - assert_eq!(jvm.invoke_virtual::<_, i32>(&stdin, "read", "()I", ()).await?, 0x41); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&stdin, "java/io/InputStream", "read", "()I", ()).await?, + 0x41 + ); let mut bytes = jvm.instantiate_array("B", 1).await?; jvm.store_array(&mut bytes, 0, [7i8]).await?; diff --git a/java_runtime/tests/classes/java/lang/test_thread.rs b/java_runtime/tests/classes/java/lang/test_thread.rs index 0ee62974..f160157e 100644 --- a/java_runtime/tests/classes/java/lang/test_thread.rs +++ b/java_runtime/tests/classes/java/lang/test_thread.rs @@ -53,16 +53,24 @@ async fn test_thread() -> Result<()> { let thread = jvm .new_class("java/lang/Thread", "(Ljava/lang/Runnable;)V", (test_class.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&thread, "start", "()V", []).await?; + let _: () = jvm.invoke_virtual(&thread, &thread.class_definition().name(), "start", "()V", []).await?; - let _: () = jvm.invoke_virtual(&thread, "join", "()V", []).await?; + let _: () = jvm.invoke_virtual(&thread, &thread.class_definition().name(), "join", "()V", []).await?; let ran: bool = jvm.get_field(&test_class, "ran", "Z").await?; assert!(ran); - assert!(!jvm.invoke_virtual::<_, bool>(&thread, "isAlive", "()Z", ()).await?); - let _: () = jvm.invoke_virtual(&thread, "setDaemon", "(Z)V", (true,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&thread, "isDaemon", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&thread, &thread.class_definition().name(), "isAlive", "()Z", ()) + .await? + ); + let _: () = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "setDaemon", "(Z)V", (true,)) + .await?; + assert!( + jvm.invoke_virtual::<_, bool>(&thread, &thread.class_definition().name(), "isDaemon", "()Z", ()) + .await? + ); Ok(()) } @@ -84,23 +92,41 @@ async fn test_thread_cldc_metadata_and_state() -> Result<()> { .await?; assert!(jvm.is_instance(&*thread, "java/lang/Runnable")); - let name = jvm.invoke_virtual(&thread, "getName", "()Ljava/lang/String;", ()).await?; + let name = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "worker"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&thread, "getPriority", "()I", ()).await?, 5); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&thread, &thread.class_definition().name(), "getPriority", "()I", ()) + .await?, + 5 + ); assert_eq!(jvm.get_static_field::("java/lang/Thread", "MIN_PRIORITY", "I").await?, 1); assert_eq!(jvm.get_static_field::("java/lang/Thread", "NORM_PRIORITY", "I").await?, 5); assert_eq!(jvm.get_static_field::("java/lang/Thread", "MAX_PRIORITY", "I").await?, 10); - let _: () = jvm.invoke_virtual(&thread, "setPriority", "(I)V", (7,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&thread, "getPriority", "()I", ()).await?, 7); - let text = jvm.invoke_virtual(&thread, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "setPriority", "(I)V", (7,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&thread, &thread.class_definition().name(), "getPriority", "()I", ()) + .await?, + 7 + ); + let text = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "Thread[worker,7]"); - let _: () = jvm.invoke_virtual(&thread, "interrupt", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "interrupt", "()V", ()) + .await?; assert!(jvm.get_field::(&thread, "interrupted", "Z").await?); assert!(jvm.invoke_static::<_, i32>("java/lang/Thread", "activeCount", "()I", ()).await? >= 1); - let result: Result<()> = jvm.invoke_virtual(&thread, "setPriority", "(I)V", (11,)).await; + let result: Result<()> = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "setPriority", "(I)V", (11,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("invalid priority must throw IllegalArgumentException"); }; @@ -142,10 +168,13 @@ async fn test_thread_jdk12_metadata_name_interrupt_and_daemon_state() -> Result< assert_eq!(flags, expected, "wrong flags for Thread.{name}{descriptor}"); } - let original_name = jvm.invoke_virtual(&thread, "getName", "()Ljava/lang/String;", ()).await?; + let original_name = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; let result: Result<()> = jvm .invoke_virtual( &thread, + &thread.class_definition().name(), "setName", "(Ljava/lang/String;)V", (ClassInstanceRef::::new(None),), @@ -155,46 +184,83 @@ async fn test_thread_jdk12_metadata_name_interrupt_and_daemon_state() -> Result< panic!("setName(null) must throw NullPointerException"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let unchanged_name = jvm.invoke_virtual(&thread, "getName", "()Ljava/lang/String;", ()).await?; + let unchanged_name = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!( JavaLangString::to_rust_string(&jvm, &unchanged_name).await?, JavaLangString::to_rust_string(&jvm, &original_name).await? ); let renamed = JavaLangString::from_rust_string(&jvm, "renamed").await?; - let _: () = jvm.invoke_virtual(&thread, "setName", "(Ljava/lang/String;)V", (renamed,)).await?; - let actual_name = jvm.invoke_virtual(&thread, "getName", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "setName", "(Ljava/lang/String;)V", (renamed,)) + .await?; + let actual_name = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual_name).await?, "renamed"); - assert!(!jvm.invoke_virtual::<_, bool>(&thread, "isDaemon", "()Z", ()).await?); - let _: () = jvm.invoke_virtual(&thread, "setDaemon", "(Z)V", (true,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&thread, "isDaemon", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&thread, &thread.class_definition().name(), "isDaemon", "()Z", ()) + .await? + ); + let _: () = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "setDaemon", "(Z)V", (true,)) + .await?; + assert!( + jvm.invoke_virtual::<_, bool>(&thread, &thread.class_definition().name(), "isDaemon", "()Z", ()) + .await? + ); - assert!(!jvm.invoke_virtual::<_, bool>(&thread, "isInterrupted", "()Z", ()).await?); - let _: () = jvm.invoke_virtual(&thread, "interrupt", "()V", ()).await?; - assert!(jvm.invoke_virtual::<_, bool>(&thread, "isInterrupted", "()Z", ()).await?); - assert!(jvm.invoke_virtual::<_, bool>(&thread, "isInterrupted", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&thread, &thread.class_definition().name(), "isInterrupted", "()Z", ()) + .await? + ); + let _: () = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "interrupt", "()V", ()) + .await?; + assert!( + jvm.invoke_virtual::<_, bool>(&thread, &thread.class_definition().name(), "isInterrupted", "()Z", ()) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&thread, &thread.class_definition().name(), "isInterrupted", "()Z", ()) + .await? + ); let current = jvm.invoke_static("java/lang/Thread", "currentThread", "()Ljava/lang/Thread;", ()).await?; - let _: () = jvm.invoke_virtual(¤t, "interrupt", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(¤t, ¤t.class_definition().name(), "interrupt", "()V", ()) + .await?; assert!(jvm.invoke_static::<_, bool>("java/lang/Thread", "interrupted", "()Z", ()).await?); assert!(!jvm.invoke_static::<_, bool>("java/lang/Thread", "interrupted", "()Z", ()).await?); - assert!(!jvm.invoke_virtual::<_, bool>(¤t, "isInterrupted", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(¤t, ¤t.class_definition().name(), "isInterrupted", "()Z", ()) + .await? + ); assert!(!jvm.get_field::(¤t, "interrupted", "Z").await?); - let result: Result<()> = jvm.invoke_virtual(&thread, "join", "(J)V", (-1i64,)).await; + let result: Result<()> = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "join", "(J)V", (-1i64,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("join(-1) must throw IllegalArgumentException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalArgumentException")); - let _: () = jvm.invoke_virtual(&thread, "start", "()V", ()).await?; - let result: Result<()> = jvm.invoke_virtual(&thread, "setDaemon", "(Z)V", (false,)).await; + let _: () = jvm.invoke_virtual(&thread, &thread.class_definition().name(), "start", "()V", ()).await?; + let result: Result<()> = jvm + .invoke_virtual(&thread, &thread.class_definition().name(), "setDaemon", "(Z)V", (false,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("setDaemon after start must throw IllegalThreadStateException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalThreadStateException")); - assert!(jvm.invoke_virtual::<_, bool>(&thread, "isDaemon", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&thread, &thread.class_definition().name(), "isDaemon", "()Z", ()) + .await? + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/lang/test_throwable.rs b/java_runtime/tests/classes/java/lang/test_throwable.rs index e3417649..1a253139 100644 --- a/java_runtime/tests/classes/java/lang/test_throwable.rs +++ b/java_runtime/tests/classes/java/lang/test_throwable.rs @@ -12,15 +12,27 @@ async fn test_to_string() -> Result<()> { let message = JavaLangString::from_rust_string(&jvm, "test message").await?; let throwable = jvm.new_class("java/lang/Throwable", "(Ljava/lang/String;)V", (message,)).await?; - let to_string = jvm.invoke_virtual(&throwable, "toString", "()Ljava/lang/String;", ()).await?; + let to_string = jvm + .invoke_virtual(&throwable, &throwable.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; let result = JavaLangString::to_rust_string(&jvm, &to_string).await?; assert_eq!(result, "java.lang.Throwable: test message"); - let message: ClassInstanceRef = jvm.invoke_virtual(&throwable, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual(&throwable, &throwable.class_definition().name(), "getMessage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, "test message"); - let localized: ClassInstanceRef = jvm.invoke_virtual(&throwable, "getLocalizedMessage", "()Ljava/lang/String;", ()).await?; + let localized: ClassInstanceRef = jvm + .invoke_virtual( + &throwable, + &throwable.class_definition().name(), + "getLocalizedMessage", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(localized.identity(), message.identity()); Ok(()) @@ -42,10 +54,24 @@ async fn test_stacktrace() -> Result<()> { .await?; let _: () = jvm - .invoke_virtual(&exception, "printStackTrace", "(Ljava/io/PrintWriter;)V", (print_writer,)) + .invoke_virtual( + &exception, + &exception.class_definition().name(), + "printStackTrace", + "(Ljava/io/PrintWriter;)V", + (print_writer,), + ) .await?; - let result: ClassInstanceRef = jvm.invoke_virtual(&string_writer, "toString", "()Ljava/lang/String;", ()).await?; + let result: ClassInstanceRef = jvm + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; let result = JavaLangString::to_rust_string(&jvm, &result).await?; assert_eq!( @@ -85,10 +111,24 @@ async fn test_print_stack_trace_with_cause() -> Result<()> { .await?; let _: () = jvm - .invoke_virtual(&throwable, "printStackTrace", "(Ljava/io/PrintWriter;)V", (print_writer,)) + .invoke_virtual( + &throwable, + &throwable.class_definition().name(), + "printStackTrace", + "(Ljava/io/PrintWriter;)V", + (print_writer,), + ) .await?; - let result: ClassInstanceRef = jvm.invoke_virtual(&string_writer, "toString", "()Ljava/lang/String;", ()).await?; + let result: ClassInstanceRef = jvm + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; let result = JavaLangString::to_rust_string(&jvm, &result).await?; assert_eq!( diff --git a/java_runtime/tests/classes/java/net/test_jar_url_connection.rs b/java_runtime/tests/classes/java/net/test_jar_url_connection.rs index c61e1d7d..fc22ac43 100644 --- a/java_runtime/tests/classes/java/net/test_jar_url_connection.rs +++ b/java_runtime/tests/classes/java/net/test_jar_url_connection.rs @@ -11,14 +11,46 @@ async fn test_jar_filename() -> Result<()> { let connection = jvm.new_class("org/rustjava/net/JarURLConnection", "(Ljava/net/URL;)V", (url,)).await?; - let jar_file_url = jvm.invoke_virtual(&connection, "getJarFileURL", "()Ljava/net/URL;", ()).await?; - let file = jvm.invoke_virtual(&jar_file_url, "getFile", "()Ljava/lang/String;", ()).await?; - let protocol = jvm.invoke_virtual(&jar_file_url, "getProtocol", "()Ljava/lang/String;", ()).await?; + let jar_file_url = jvm + .invoke_virtual( + &connection, + &connection.class_definition().name(), + "getJarFileURL", + "()Ljava/net/URL;", + (), + ) + .await?; + let file = jvm + .invoke_virtual( + &jar_file_url, + &jar_file_url.class_definition().name(), + "getFile", + "()Ljava/lang/String;", + (), + ) + .await?; + let protocol = jvm + .invoke_virtual( + &jar_file_url, + &jar_file_url.class_definition().name(), + "getProtocol", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &file).await?, "path/to/file.jar"); assert_eq!(JavaLangString::to_rust_string(&jvm, &protocol).await?, "file"); - let entry_name = jvm.invoke_virtual(&connection, "getEntryName", "()Ljava/lang/String;", ()).await?; + let entry_name = jvm + .invoke_virtual( + &connection, + &connection.class_definition().name(), + "getEntryName", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &entry_name).await?, "path/to/entry"); Ok(()) diff --git a/java_runtime/tests/classes/java/net/test_url_class_loader.rs b/java_runtime/tests/classes/java/net/test_url_class_loader.rs index ce425178..c9c78fdc 100644 --- a/java_runtime/tests/classes/java/net/test_url_class_loader.rs +++ b/java_runtime/tests/classes/java/net/test_url_class_loader.rs @@ -22,13 +22,29 @@ async fn test_jar_loading() -> Result<()> { let resource_name = JavaLangString::from_rust_string(&jvm, "test.txt").await?; let resource = jvm - .invoke_virtual(&class_loader, "findResource", "(Ljava/lang/String;)Ljava/net/URL;", (resource_name,)) + .invoke_virtual( + &class_loader, + &class_loader.class_definition().name(), + "findResource", + "(Ljava/lang/String;)Ljava/net/URL;", + (resource_name,), + ) .await?; - let stream = jvm.invoke_virtual(&resource, "openStream", "()Ljava/io/InputStream;", ()).await?; + let stream = jvm + .invoke_virtual( + &resource, + &resource.class_definition().name(), + "openStream", + "()Ljava/io/InputStream;", + (), + ) + .await?; let buf = jvm.instantiate_array("B", 17).await?; - let len: i32 = jvm.invoke_virtual(&stream, "read", "([B)I", (buf.clone(),)).await?; + let len: i32 = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([B)I", (buf.clone(),)) + .await?; let mut data = vec![0; len as _]; jvm.array_raw_buffer(&buf).await?.read(0, &mut data)?; @@ -57,6 +73,7 @@ async fn test_jar_loading_with_slash() -> Result<()> { let stream = jvm .invoke_virtual( &class_loader, + &class_loader.class_definition().name(), "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;", (resource_name,), @@ -64,7 +81,9 @@ async fn test_jar_loading_with_slash() -> Result<()> { .await?; let buf = jvm.instantiate_array("B", 17).await?; - let len: i32 = jvm.invoke_virtual(&stream, "read", "([B)I", (buf.clone(),)).await?; + let len: i32 = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([B)I", (buf.clone(),)) + .await?; let mut data = vec![0; len as _]; jvm.array_raw_buffer(&buf).await?.read(0, &mut data)?; @@ -90,13 +109,29 @@ async fn test_load_from_dir() -> Result<()> { let resource_name = JavaLangString::from_rust_string(&jvm, "test.txt").await?; let resource = jvm - .invoke_virtual(&class_loader, "findResource", "(Ljava/lang/String;)Ljava/net/URL;", (resource_name,)) + .invoke_virtual( + &class_loader, + &class_loader.class_definition().name(), + "findResource", + "(Ljava/lang/String;)Ljava/net/URL;", + (resource_name,), + ) .await?; - let stream = jvm.invoke_virtual(&resource, "openStream", "()Ljava/io/InputStream;", ()).await?; + let stream = jvm + .invoke_virtual( + &resource, + &resource.class_definition().name(), + "openStream", + "()Ljava/io/InputStream;", + (), + ) + .await?; let buf = jvm.instantiate_array("B", 17).await?; - let len: i32 = jvm.invoke_virtual(&stream, "read", "([B)I", (buf.clone(),)).await?; + let len: i32 = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([B)I", (buf.clone(),)) + .await?; let mut data = vec![0; len as _]; jvm.array_raw_buffer(&buf).await?.read(0, &mut data)?; @@ -123,7 +158,13 @@ async fn test_jar_loading_no_file() -> Result<()> { let resource_name = JavaLangString::from_rust_string(&jvm, "does_not_exists.txt").await?; let resource: ClassInstanceRef = jvm - .invoke_virtual(&class_loader, "findResource", "(Ljava/lang/String;)Ljava/net/URL;", (resource_name,)) + .invoke_virtual( + &class_loader, + &class_loader.class_definition().name(), + "findResource", + "(Ljava/lang/String;)Ljava/net/URL;", + (resource_name,), + ) .await?; assert!(resource.is_null()); @@ -147,7 +188,13 @@ async fn test_load_from_dir_no_file() -> Result<()> { let resource_name = JavaLangString::from_rust_string(&jvm, "does_not_exists.txt").await?; let resource: ClassInstanceRef = jvm - .invoke_virtual(&class_loader, "findResource", "(Ljava/lang/String;)Ljava/net/URL;", (resource_name,)) + .invoke_virtual( + &class_loader, + &class_loader.class_definition().name(), + "findResource", + "(Ljava/lang/String;)Ljava/net/URL;", + (resource_name,), + ) .await?; assert!(resource.is_null()); @@ -172,7 +219,13 @@ async fn test_missing_url_does_not_prevent_later_jar_lookup() -> Result<()> { .await?; let resource_name = JavaLangString::from_rust_string(&jvm, "test.txt").await?; let resource: ClassInstanceRef = jvm - .invoke_virtual(&class_loader, "findResource", "(Ljava/lang/String;)Ljava/net/URL;", (resource_name,)) + .invoke_virtual( + &class_loader, + &class_loader.class_definition().name(), + "findResource", + "(Ljava/lang/String;)Ljava/net/URL;", + (resource_name,), + ) .await?; assert!(!resource.is_null()); @@ -194,7 +247,13 @@ async fn test_url_class_loader_does_not_load_rustjar_classes() -> Result<()> { let name = JavaLangString::from_rust_string(&jvm, "java/util/Random").await?; let class: ClassInstanceRef = jvm - .invoke_virtual(&class_loader, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;", (name,)) + .invoke_virtual( + &class_loader, + &class_loader.class_definition().name(), + "findClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (name,), + ) .await?; assert!(class.is_null()); diff --git a/java_runtime/tests/classes/java/text/test_date_format.rs b/java_runtime/tests/classes/java/text/test_date_format.rs index 73603f3d..8f677fb2 100644 --- a/java_runtime/tests/classes/java/text/test_date_format.rs +++ b/java_runtime/tests/classes/java/text/test_date_format.rs @@ -16,7 +16,13 @@ async fn test_date_format_factories_use_english_patterns() -> Result<()> { .invoke_static("java/text/DateFormat", "getDateInstance", "(I)Ljava/text/DateFormat;", (3,)) .await?; let text: ClassInstanceRef = jvm - .invoke_virtual(&short, "format", "(Ljava/util/Date;)Ljava/lang/String;", (date.clone(),)) + .invoke_virtual( + &short, + "java/text/DateFormat", + "format", + "(Ljava/util/Date;)Ljava/lang/String;", + (date.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "1/1/70"); @@ -24,7 +30,13 @@ async fn test_date_format_factories_use_english_patterns() -> Result<()> { .invoke_static("java/text/DateFormat", "getDateInstance", "(I)Ljava/text/DateFormat;", (2,)) .await?; let text: ClassInstanceRef = jvm - .invoke_virtual(&medium, "format", "(Ljava/util/Date;)Ljava/lang/String;", (date.clone(),)) + .invoke_virtual( + &medium, + "java/text/DateFormat", + "format", + "(Ljava/util/Date;)Ljava/lang/String;", + (date.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "Jan 1, 1970"); @@ -32,7 +44,7 @@ async fn test_date_format_factories_use_english_patterns() -> Result<()> { .invoke_static("java/text/DateFormat", "getTimeInstance", "(I)Ljava/text/DateFormat;", (3,)) .await?; let text: ClassInstanceRef = jvm - .invoke_virtual(&time, "format", "(Ljava/util/Date;)Ljava/lang/String;", (date,)) + .invoke_virtual(&time, "java/text/DateFormat", "format", "(Ljava/util/Date;)Ljava/lang/String;", (date,)) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "12:00 AM"); @@ -49,7 +61,13 @@ async fn test_simple_date_format_patterns_quotes_and_fields() -> Result<()> { .into(); let date: ClassInstanceRef = jvm.new_class("java/util/Date", "(J)V", (0i64,)).await?.into(); let text: ClassInstanceRef = jvm - .invoke_virtual(&format, "format", "(Ljava/util/Date;)Ljava/lang/String;", (date.clone(),)) + .invoke_virtual( + &format, + "java/text/SimpleDateFormat", + "format", + "(Ljava/util/Date;)Ljava/lang/String;", + (date.clone(),), + ) .await?; assert_eq!( JavaLangString::to_rust_string(&jvm, &text).await?, @@ -58,7 +76,13 @@ async fn test_simple_date_format_patterns_quotes_and_fields() -> Result<()> { let field_pattern = JavaLangString::from_rust_string(&jvm, "yyyy-MM").await?; let _: () = jvm - .invoke_virtual(&format, "applyPattern", "(Ljava/lang/String;)V", (field_pattern,)) + .invoke_virtual( + &format, + "java/text/SimpleDateFormat", + "applyPattern", + "(Ljava/lang/String;)V", + (field_pattern,), + ) .await?; let prefix = JavaLangString::from_rust_string(&jvm, "on ").await?; let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (prefix,)).await?.into(); @@ -66,15 +90,26 @@ async fn test_simple_date_format_patterns_quotes_and_fields() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/SimpleDateFormat", "format", "(Ljava/util/Date;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (date, buffer.clone(), position.clone()), ) .await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "on 1970-01"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getBeginIndex", "()I", ()).await?, 3); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getEndIndex", "()I", ()).await?, 7); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getBeginIndex", "()I", ()) + .await?, + 3 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getEndIndex", "()I", ()) + .await?, + 7 + ); Ok(()) } @@ -92,21 +127,31 @@ async fn test_date_format_timezone_and_calendar_state() -> Result<()> { .new_class("java/util/SimpleTimeZone", "(ILjava/lang/String;)V", (9 * 60 * 60 * 1000, id)) .await? .into(); - let _: () = jvm.invoke_virtual(&format, "setTimeZone", "(Ljava/util/TimeZone;)V", (timezone,)).await?; + let _: () = jvm + .invoke_virtual(&format, "java/text/DateFormat", "setTimeZone", "(Ljava/util/TimeZone;)V", (timezone,)) + .await?; let date: ClassInstanceRef = jvm.new_class("java/util/Date", "(J)V", (0i64,)).await?.into(); let text: ClassInstanceRef = jvm - .invoke_virtual(&format, "format", "(Ljava/util/Date;)Ljava/lang/String;", (date,)) + .invoke_virtual(&format, "java/text/DateFormat", "format", "(Ljava/util/Date;)Ljava/lang/String;", (date,)) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "1970-01-01 09:00:00 GMT+09:00"); - let actual: ClassInstanceRef = jvm.invoke_virtual(&format, "getTimeZone", "()Ljava/util/TimeZone;", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&format, "java/text/DateFormat", "getTimeZone", "()Ljava/util/TimeZone;", ()) + .await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&actual, "getRawOffset", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&actual, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?, 9 * 60 * 60 * 1000 ); - let _: () = jvm.invoke_virtual(&format, "setLenient", "(Z)V", (false,)).await?; - assert!(!jvm.invoke_virtual::<_, bool>(&format, "isLenient", "()Z", ()).await?); + let _: () = jvm + .invoke_virtual(&format, "java/text/DateFormat", "setLenient", "(Z)V", (false,)) + .await?; + assert!( + !jvm.invoke_virtual::<_, bool>(&format, "java/text/DateFormat", "isLenient", "()Z", ()) + .await? + ); Ok(()) } @@ -124,27 +169,56 @@ async fn test_simple_date_format_parse_and_positions() -> Result<()> { let date: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/SimpleDateFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/util/Date;", (source, position.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&date, "getTime", "()J", ()).await?, 97_445_006); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getIndex", "()I", ()).await?, 23); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&date, "java/util/Date", "getTime", "()J", ()).await?, + 97_445_006 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getIndex", "()I", ()) + .await?, + 23 + ); let text_pattern = JavaLangString::from_rust_string(&jvm, "MMMM d, yyyy h:mm a z").await?; let _: () = jvm - .invoke_virtual(&format, "applyPattern", "(Ljava/lang/String;)V", (text_pattern,)) + .invoke_virtual( + &format, + "java/text/SimpleDateFormat", + "applyPattern", + "(Ljava/lang/String;)V", + (text_pattern,), + ) .await?; let source = JavaLangString::from_rust_string(&jvm, "January 2, 1970 3:04 PM GMT").await?; let date: ClassInstanceRef = jvm - .invoke_virtual(&format, "parse", "(Ljava/lang/String;)Ljava/util/Date;", (source,)) + .invoke_virtual( + &format, + "java/text/SimpleDateFormat", + "parse", + "(Ljava/lang/String;)Ljava/util/Date;", + (source,), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&date, "getTime", "()J", ()).await?, 140_640_000); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&date, "java/util/Date", "getTime", "()J", ()).await?, + 140_640_000 + ); let invalid = JavaLangString::from_rust_string(&jvm, "not a date").await?; let result = jvm - .invoke_virtual::<_, ClassInstanceRef>(&format, "parse", "(Ljava/lang/String;)Ljava/util/Date;", (invalid,)) + .invoke_virtual::<_, ClassInstanceRef>( + &format, + "java/text/SimpleDateFormat", + "parse", + "(Ljava/lang/String;)Ljava/util/Date;", + (invalid,), + ) .await; assert!(matches!(result, Err(JavaError::JavaException(_)))); @@ -165,43 +239,69 @@ async fn test_simple_date_format_uses_utf16_positions() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/SimpleDateFormat", "format", "(Ljava/util/Date;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (date, buffer.clone(), position.clone()), ) .await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "\u{1f600}1970"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getBeginIndex", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getEndIndex", "()I", ()).await?, 6); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getBeginIndex", "()I", ()) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getEndIndex", "()I", ()) + .await?, + 6 + ); let pattern = JavaLangString::from_rust_string(&jvm, "yyyy-MM-dd").await?; - let _: () = jvm.invoke_virtual(&format, "applyPattern", "(Ljava/lang/String;)V", (pattern,)).await?; + let _: () = jvm + .invoke_virtual(&format, "java/text/SimpleDateFormat", "applyPattern", "(Ljava/lang/String;)V", (pattern,)) + .await?; let source = JavaLangString::from_rust_string(&jvm, "\u{1f600}1970-01-02").await?; let position: ClassInstanceRef = jvm.new_class("java/text/ParsePosition", "(I)V", (2,)).await?.into(); let date: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/SimpleDateFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/util/Date;", (source, position.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&date, "getTime", "()J", ()).await?, 86_400_000); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getIndex", "()I", ()).await?, 12); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&date, "java/util/Date", "getTime", "()J", ()).await?, + 86_400_000 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getIndex", "()I", ()) + .await?, + 12 + ); let source = JavaLangString::from_rust_string(&jvm, "\u{1f600}197x").await?; let position: ClassInstanceRef = jvm.new_class("java/text/ParsePosition", "(I)V", (2,)).await?.into(); let date: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/SimpleDateFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/util/Date;", (source, position.clone()), ) .await?; assert!(date.is_null()); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getErrorIndex", "()I", ()).await?, 5); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getErrorIndex", "()I", ()) + .await?, + 5 + ); Ok(()) } @@ -214,26 +314,45 @@ async fn test_date_format_clone_and_calendar_leniency_are_isolated() -> Result<( .new_class("java/text/SimpleDateFormat", "(Ljava/lang/String;)V", (pattern,)) .await? .into(); - let calendar: ClassInstanceRef = jvm.invoke_virtual(&format, "getCalendar", "()Ljava/util/Calendar;", ()).await?; - let _: () = jvm.invoke_virtual(&calendar, "setTimeInMillis", "(J)V", (0i64,)).await?; + let calendar: ClassInstanceRef = jvm + .invoke_virtual(&format, "java/text/DateFormat", "getCalendar", "()Ljava/util/Calendar;", ()) + .await?; + let _: () = jvm + .invoke_virtual(&calendar, "java/util/Calendar", "setTimeInMillis", "(J)V", (0i64,)) + .await?; - let cloned: ClassInstanceRef = jvm.invoke_virtual(&format, "clone", "()Ljava/lang/Object;", ()).await?; - let cloned_calendar: ClassInstanceRef = jvm.invoke_virtual(&cloned, "getCalendar", "()Ljava/util/Calendar;", ()).await?; - let _: () = jvm.invoke_virtual(&cloned_calendar, "setTimeInMillis", "(J)V", (86_400_000i64,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&calendar, "get", "(I)I", (5,)).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&cloned_calendar, "get", "(I)I", (5,)).await?, 2); + let cloned: ClassInstanceRef = jvm + .invoke_virtual(&format, "java/text/DateFormat", "clone", "()Ljava/lang/Object;", ()) + .await?; + let cloned_calendar: ClassInstanceRef = jvm + .invoke_virtual(&cloned, "java/text/DateFormat", "getCalendar", "()Ljava/util/Calendar;", ()) + .await?; + let _: () = jvm + .invoke_virtual(&cloned_calendar, "java/util/Calendar", "setTimeInMillis", "(J)V", (86_400_000i64,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&calendar, "java/util/Calendar", "get", "(I)I", (5,)).await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&cloned_calendar, "java/util/Calendar", "get", "(I)I", (5,)) + .await?, + 2 + ); let other: ClassInstanceRef = jvm .invoke_static("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;", ()) .await?; - let _: () = jvm.invoke_virtual(&other, "setTimeInMillis", "(J)V", (0i64,)).await?; + let _: () = jvm + .invoke_virtual(&other, "java/util/Calendar", "setTimeInMillis", "(J)V", (0i64,)) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&calendar, "equals", "(Ljava/lang/Object;)Z", (other.clone(),)) + jvm.invoke_virtual::<_, bool>(&calendar, "java/util/Calendar", "equals", "(Ljava/lang/Object;)Z", (other.clone(),)) .await? ); - let _: () = jvm.invoke_virtual(&other, "setLenient", "(Z)V", (false,)).await?; + let _: () = jvm.invoke_virtual(&other, "java/util/Calendar", "setLenient", "(Z)V", (false,)).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&calendar, "equals", "(Ljava/lang/Object;)Z", (other,)) + !jvm.invoke_virtual::<_, bool>(&calendar, "java/util/Calendar", "equals", "(Ljava/lang/Object;)Z", (other,)) .await? ); diff --git a/java_runtime/tests/classes/java/text/test_format.rs b/java_runtime/tests/classes/java/text/test_format.rs index 29856c64..7d7f997f 100644 --- a/java_runtime/tests/classes/java/text/test_format.rs +++ b/java_runtime/tests/classes/java/text/test_format.rs @@ -24,25 +24,53 @@ async fn test_field_position_accessors_and_equality() -> Result<()> { let jvm = test_jvm().await?; let position: ClassInstanceRef = jvm.new_class("java/text/FieldPosition", "(I)V", (1,)).await?.into(); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getField", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getBeginIndex", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getEndIndex", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getField", "()I", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getBeginIndex", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getEndIndex", "()I", ()) + .await?, + 0 + ); - let _: () = jvm.invoke_virtual(&position, "setBeginIndex", "(I)V", (3,)).await?; - let _: () = jvm.invoke_virtual(&position, "setEndIndex", "(I)V", (7,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getBeginIndex", "()I", ()).await?, 3); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getEndIndex", "()I", ()).await?, 7); + let _: () = jvm + .invoke_virtual(&position, "java/text/FieldPosition", "setBeginIndex", "(I)V", (3,)) + .await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/FieldPosition", "setEndIndex", "(I)V", (7,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getBeginIndex", "()I", ()) + .await?, + 3 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getEndIndex", "()I", ()) + .await?, + 7 + ); let same: ClassInstanceRef = jvm.new_class("java/text/FieldPosition", "(I)V", (1,)).await?.into(); - let _: () = jvm.invoke_virtual(&same, "setBeginIndex", "(I)V", (3,)).await?; - let _: () = jvm.invoke_virtual(&same, "setEndIndex", "(I)V", (7,)).await?; + let _: () = jvm + .invoke_virtual(&same, "java/text/FieldPosition", "setBeginIndex", "(I)V", (3,)) + .await?; + let _: () = jvm.invoke_virtual(&same, "java/text/FieldPosition", "setEndIndex", "(I)V", (7,)).await?; assert!( - jvm.invoke_virtual::<_, bool>(&position, "equals", "(Ljava/lang/Object;)Z", (same.clone(),)) + jvm.invoke_virtual::<_, bool>(&position, "java/text/FieldPosition", "equals", "(Ljava/lang/Object;)Z", (same.clone(),)) .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&position, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&same, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&same, "java/text/FieldPosition", "hashCode", "()I", ()) + .await? ); Ok(()) @@ -53,18 +81,38 @@ async fn test_parse_position_accessors_and_equality() -> Result<()> { let jvm = test_jvm().await?; let position: ClassInstanceRef = jvm.new_class("java/text/ParsePosition", "(I)V", (2,)).await?.into(); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getIndex", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getErrorIndex", "()I", ()).await?, -1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getIndex", "()I", ()) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getErrorIndex", "()I", ()) + .await?, + -1 + ); - let _: () = jvm.invoke_virtual(&position, "setIndex", "(I)V", (5,)).await?; - let _: () = jvm.invoke_virtual(&position, "setErrorIndex", "(I)V", (4,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getIndex", "()I", ()).await?, 5); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getErrorIndex", "()I", ()).await?, 4); + let _: () = jvm.invoke_virtual(&position, "java/text/ParsePosition", "setIndex", "(I)V", (5,)).await?; + let _: () = jvm + .invoke_virtual(&position, "java/text/ParsePosition", "setErrorIndex", "(I)V", (4,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getIndex", "()I", ()) + .await?, + 5 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getErrorIndex", "()I", ()) + .await?, + 4 + ); let same: ClassInstanceRef = jvm.new_class("java/text/ParsePosition", "(I)V", (5,)).await?.into(); - let _: () = jvm.invoke_virtual(&same, "setErrorIndex", "(I)V", (4,)).await?; + let _: () = jvm + .invoke_virtual(&same, "java/text/ParsePosition", "setErrorIndex", "(I)V", (4,)) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&position, "equals", "(Ljava/lang/Object;)Z", (same,)) + jvm.invoke_virtual::<_, bool>(&position, "java/text/ParsePosition", "equals", "(Ljava/lang/Object;)Z", (same,)) .await? ); @@ -80,8 +128,14 @@ async fn test_parse_exception_error_offset_and_message() -> Result<()> { .await? .into(); - assert_eq!(jvm.invoke_virtual::<_, i32>(&exception, "getErrorOffset", "()I", ()).await?, 6); - let actual: ClassInstanceRef = jvm.invoke_virtual(&exception, "getMessage", "()Ljava/lang/String;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&exception, "java/text/ParseException", "getErrorOffset", "()I", ()) + .await?, + 6 + ); + let actual: ClassInstanceRef = jvm + .invoke_virtual(&exception, "java/text/ParseException", "getMessage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, "bad date"); Ok(()) @@ -96,13 +150,19 @@ async fn test_format_polymorphic_format_and_parse_object() -> Result<()> { let format: ClassInstanceRef = ClassInstanceRef::new(number.instance); let value: ClassInstanceRef = jvm.new_class("java/lang/Long", "(J)V", (1234i64,)).await?.into(); let text: ClassInstanceRef = jvm - .invoke_virtual(&format, "format", "(Ljava/lang/Object;)Ljava/lang/String;", (value,)) + .invoke_virtual(&format, "java/text/Format", "format", "(Ljava/lang/Object;)Ljava/lang/String;", (value,)) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "1,234"); let source = JavaLangString::from_rust_string(&jvm, "1,234").await?; let parsed: ClassInstanceRef = jvm - .invoke_virtual(&format, "parseObject", "(Ljava/lang/String;)Ljava/lang/Object;", (source,)) + .invoke_virtual( + &format, + "java/text/Format", + "parseObject", + "(Ljava/lang/String;)Ljava/lang/Object;", + (source,), + ) .await?; assert!(jvm.is_instance(&**parsed, "java/lang/Long")); diff --git a/java_runtime/tests/classes/java/text/test_number_format.rs b/java_runtime/tests/classes/java/text/test_number_format.rs index 8d6e5975..ad8d0ae1 100644 --- a/java_runtime/tests/classes/java/text/test_number_format.rs +++ b/java_runtime/tests/classes/java/text/test_number_format.rs @@ -14,21 +14,29 @@ async fn test_number_format_factories_format_values() -> Result<()> { let number: ClassInstanceRef = jvm .invoke_static("java/text/NumberFormat", "getInstance", "()Ljava/text/NumberFormat;", ()) .await?; - let integer: ClassInstanceRef = jvm.invoke_virtual(&number, "format", "(J)Ljava/lang/String;", (1_234_567i64,)).await?; + let integer: ClassInstanceRef = jvm + .invoke_virtual(&number, "java/text/NumberFormat", "format", "(J)Ljava/lang/String;", (1_234_567i64,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &integer).await?, "1,234,567"); - let decimal: ClassInstanceRef = jvm.invoke_virtual(&number, "format", "(D)Ljava/lang/String;", (1234.5f64,)).await?; + let decimal: ClassInstanceRef = jvm + .invoke_virtual(&number, "java/text/NumberFormat", "format", "(D)Ljava/lang/String;", (1234.5f64,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &decimal).await?, "1,234.5"); let percent: ClassInstanceRef = jvm .invoke_static("java/text/NumberFormat", "getPercentInstance", "()Ljava/text/NumberFormat;", ()) .await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&percent, "format", "(D)Ljava/lang/String;", (0.12f64,)).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&percent, "java/text/NumberFormat", "format", "(D)Ljava/lang/String;", (0.12f64,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "12%"); let currency: ClassInstanceRef = jvm .invoke_static("java/text/NumberFormat", "getCurrencyInstance", "()Ljava/text/NumberFormat;", ()) .await?; - let text: ClassInstanceRef = jvm.invoke_virtual(¤cy, "format", "(D)Ljava/lang/String;", (1234.5f64,)).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(¤cy, "java/text/NumberFormat", "format", "(D)Ljava/lang/String;", (1234.5f64,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "$1,234.50"); Ok(()) @@ -41,8 +49,15 @@ async fn test_number_format_integer_factories() -> Result<()> { let default: ClassInstanceRef = jvm .invoke_static("java/text/NumberFormat", "getIntegerInstance", "()Ljava/text/NumberFormat;", ()) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&default, "getMaximumFractionDigits", "()I", ()).await?, 0); - assert!(jvm.invoke_virtual::<_, bool>(&default, "isParseIntegerOnly", "()Z", ()).await?); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&default, "java/text/NumberFormat", "getMaximumFractionDigits", "()I", ()) + .await?, + 0 + ); + assert!( + jvm.invoke_virtual::<_, bool>(&default, "java/text/NumberFormat", "isParseIntegerOnly", "()Z", ()) + .await? + ); let locale: ClassInstanceRef = jvm.invoke_static("java/util/Locale", "getDefault", "()Ljava/util/Locale;", ()).await?; let integer: ClassInstanceRef = jvm @@ -53,7 +68,9 @@ async fn test_number_format_integer_factories() -> Result<()> { (locale,), ) .await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&integer, "format", "(D)Ljava/lang/String;", (1234.6f64,)).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&integer, "java/text/NumberFormat", "format", "(D)Ljava/lang/String;", (1234.6f64,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "1,235"); let source = JavaLangString::from_rust_string(&jvm, "1,234.5rest").await?; @@ -61,13 +78,21 @@ async fn test_number_format_integer_factories() -> Result<()> { let parsed: ClassInstanceRef = jvm .invoke_virtual( &integer, + "java/text/NumberFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;", (source, position.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&parsed, "longValue", "()J", ()).await?, 1234); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getIndex", "()I", ()).await?, 5); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&parsed, "java/lang/Long", "longValue", "()J", ()).await?, + 1234 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getIndex", "()I", ()) + .await?, + 5 + ); Ok(()) } @@ -79,14 +104,29 @@ async fn test_number_format_digit_and_grouping_settings() -> Result<()> { .invoke_static("java/text/NumberFormat", "getNumberInstance", "()Ljava/text/NumberFormat;", ()) .await?; - let _: () = jvm.invoke_virtual(&number, "setGroupingUsed", "(Z)V", (false,)).await?; - let _: () = jvm.invoke_virtual(&number, "setMinimumFractionDigits", "(I)V", (2,)).await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&number, "format", "(D)Ljava/lang/String;", (1234.5f64,)).await?; + let _: () = jvm + .invoke_virtual(&number, "java/text/NumberFormat", "setGroupingUsed", "(Z)V", (false,)) + .await?; + let _: () = jvm + .invoke_virtual(&number, "java/text/NumberFormat", "setMinimumFractionDigits", "(I)V", (2,)) + .await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&number, "java/text/NumberFormat", "format", "(D)Ljava/lang/String;", (1234.5f64,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "1234.50"); - let _: () = jvm.invoke_virtual(&number, "setMaximumFractionDigits", "(I)V", (1,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&number, "getMinimumFractionDigits", "()I", ()).await?, 1); - assert!(!jvm.invoke_virtual::<_, bool>(&number, "isGroupingUsed", "()Z", ()).await?); + let _: () = jvm + .invoke_virtual(&number, "java/text/NumberFormat", "setMaximumFractionDigits", "(I)V", (1,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&number, "java/text/NumberFormat", "getMinimumFractionDigits", "()I", ()) + .await?, + 1 + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&number, "java/text/NumberFormat", "isGroupingUsed", "()Z", ()) + .await? + ); Ok(()) } @@ -100,26 +140,41 @@ async fn test_decimal_format_pattern_and_field_position() -> Result<()> { .await? .into(); - let text: ClassInstanceRef = jvm.invoke_virtual(&format, "format", "(D)Ljava/lang/String;", (12.3f64,)).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&format, "java/text/DecimalFormat", "format", "(D)Ljava/lang/String;", (12.3f64,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "0012.30"); let grouping = JavaLangString::from_rust_string(&jvm, "#,##0.###").await?; - let _: () = jvm.invoke_virtual(&format, "applyPattern", "(Ljava/lang/String;)V", (grouping,)).await?; + let _: () = jvm + .invoke_virtual(&format, "java/text/DecimalFormat", "applyPattern", "(Ljava/lang/String;)V", (grouping,)) + .await?; let prefix = JavaLangString::from_rust_string(&jvm, "pre ").await?; let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (prefix,)).await?.into(); let position: ClassInstanceRef = jvm.new_class("java/text/FieldPosition", "(I)V", (0,)).await?.into(); let _: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/DecimalFormat", "format", "(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (1234.5f64, buffer.clone(), position.clone()), ) .await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&buffer, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "pre 1,234.5"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getBeginIndex", "()I", ()).await?, 4); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getEndIndex", "()I", ()).await?, 9); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getBeginIndex", "()I", ()) + .await?, + 4 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/FieldPosition", "getEndIndex", "()I", ()) + .await?, + 9 + ); Ok(()) } @@ -135,33 +190,57 @@ async fn test_number_format_parse_and_positions() -> Result<()> { let parsed: ClassInstanceRef = jvm .invoke_virtual( &number, + "java/text/NumberFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;", (source, position.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, f64>(&parsed, "doubleValue", "()D", ()).await?, 1234.5); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getIndex", "()I", ()).await?, 7); + assert_eq!( + jvm.invoke_virtual::<_, f64>(&parsed, "java/lang/Double", "doubleValue", "()D", ()) + .await?, + 1234.5 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getIndex", "()I", ()) + .await?, + 7 + ); let integer_source = JavaLangString::from_rust_string(&jvm, "42").await?; let parsed: ClassInstanceRef = jvm - .invoke_virtual(&number, "parse", "(Ljava/lang/String;)Ljava/lang/Number;", (integer_source,)) + .invoke_virtual( + &number, + "java/text/NumberFormat", + "parse", + "(Ljava/lang/String;)Ljava/lang/Number;", + (integer_source,), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&parsed, "longValue", "()J", ()).await?, 42); + assert_eq!(jvm.invoke_virtual::<_, i64>(&parsed, "java/lang/Long", "longValue", "()J", ()).await?, 42); let invalid = JavaLangString::from_rust_string(&jvm, "not-a-number").await?; let position: ClassInstanceRef = jvm.new_class("java/text/ParsePosition", "(I)V", (0,)).await?.into(); let parsed: ClassInstanceRef = jvm .invoke_virtual( &number, + "java/text/NumberFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;", (invalid, position.clone()), ) .await?; assert!(parsed.is_null()); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getIndex", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getErrorIndex", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getIndex", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getErrorIndex", "()I", ()) + .await?, + 0 + ); Ok(()) } @@ -174,35 +253,72 @@ async fn test_decimal_format_quoted_affixes_and_integer_boundaries() -> Result<( .new_class("java/text/DecimalFormat", "(Ljava/lang/String;)V", (pattern,)) .await? .into(); - let text: ClassInstanceRef = jvm.invoke_virtual(&format, "format", "(J)Ljava/lang/String;", (12i64,)).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&format, "java/text/DecimalFormat", "format", "(J)Ljava/lang/String;", (12i64,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "%12"); let source = JavaLangString::from_rust_string(&jvm, "%12").await?; let parsed: ClassInstanceRef = jvm - .invoke_virtual(&format, "parse", "(Ljava/lang/String;)Ljava/lang/Number;", (source,)) + .invoke_virtual( + &format, + "java/text/DecimalFormat", + "parse", + "(Ljava/lang/String;)Ljava/lang/Number;", + (source,), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&parsed, "longValue", "()J", ()).await?, 12); + assert_eq!(jvm.invoke_virtual::<_, i64>(&parsed, "java/lang/Long", "longValue", "()J", ()).await?, 12); let apostrophe_pattern = JavaLangString::from_rust_string(&jvm, "''0").await?; let _: () = jvm - .invoke_virtual(&format, "applyPattern", "(Ljava/lang/String;)V", (apostrophe_pattern,)) + .invoke_virtual( + &format, + "java/text/DecimalFormat", + "applyPattern", + "(Ljava/lang/String;)V", + (apostrophe_pattern,), + ) + .await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&format, "java/text/DecimalFormat", "format", "(J)Ljava/lang/String;", (12i64,)) .await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&format, "format", "(J)Ljava/lang/String;", (12i64,)).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "'12"); let plain_pattern = JavaLangString::from_rust_string(&jvm, "0").await?; let _: () = jvm - .invoke_virtual(&format, "applyPattern", "(Ljava/lang/String;)V", (plain_pattern,)) + .invoke_virtual( + &format, + "java/text/DecimalFormat", + "applyPattern", + "(Ljava/lang/String;)V", + (plain_pattern,), + ) .await?; let maximum = JavaLangString::from_rust_string(&jvm, "9223372036854775807").await?; let parsed: ClassInstanceRef = jvm - .invoke_virtual(&format, "parse", "(Ljava/lang/String;)Ljava/lang/Number;", (maximum,)) + .invoke_virtual( + &format, + "java/text/DecimalFormat", + "parse", + "(Ljava/lang/String;)Ljava/lang/Number;", + (maximum,), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&parsed, "longValue", "()J", ()).await?, i64::MAX); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&parsed, "java/lang/Long", "longValue", "()J", ()).await?, + i64::MAX + ); let overflow = JavaLangString::from_rust_string(&jvm, "9223372036854775808").await?; let parsed: ClassInstanceRef = jvm - .invoke_virtual(&format, "parse", "(Ljava/lang/String;)Ljava/lang/Number;", (overflow,)) + .invoke_virtual( + &format, + "java/text/DecimalFormat", + "parse", + "(Ljava/lang/String;)Ljava/lang/Number;", + (overflow,), + ) .await?; assert!(jvm.is_instance(&**parsed, "java/lang/Double")); @@ -223,77 +339,131 @@ async fn test_decimal_format_uses_utf16_positions_and_negative_suffixes() -> Res let _: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/DecimalFormat", "format", "(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (12.3f64, buffer, integer_position.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&integer_position, "getBeginIndex", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&integer_position, "getEndIndex", "()I", ()).await?, 4); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&integer_position, "java/text/FieldPosition", "getBeginIndex", "()I", ()) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&integer_position, "java/text/FieldPosition", "getEndIndex", "()I", ()) + .await?, + 4 + ); let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?.into(); let fraction_position: ClassInstanceRef = jvm.new_class("java/text/FieldPosition", "(I)V", (1,)).await?.into(); let _: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/DecimalFormat", "format", "(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;", (12.3f64, buffer, fraction_position.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&fraction_position, "getBeginIndex", "()I", ()).await?, 5); - assert_eq!(jvm.invoke_virtual::<_, i32>(&fraction_position, "getEndIndex", "()I", ()).await?, 6); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&fraction_position, "java/text/FieldPosition", "getBeginIndex", "()I", ()) + .await?, + 5 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&fraction_position, "java/text/FieldPosition", "getEndIndex", "()I", ()) + .await?, + 6 + ); let plain_pattern = JavaLangString::from_rust_string(&jvm, "0").await?; let _: () = jvm - .invoke_virtual(&format, "applyPattern", "(Ljava/lang/String;)V", (plain_pattern,)) + .invoke_virtual( + &format, + "java/text/DecimalFormat", + "applyPattern", + "(Ljava/lang/String;)V", + (plain_pattern,), + ) .await?; let source = JavaLangString::from_rust_string(&jvm, "\u{1f600}12").await?; let position: ClassInstanceRef = jvm.new_class("java/text/ParsePosition", "(I)V", (2,)).await?.into(); let parsed: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/DecimalFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;", (source, position.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&parsed, "longValue", "()J", ()).await?, 12); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getIndex", "()I", ()).await?, 4); + assert_eq!(jvm.invoke_virtual::<_, i64>(&parsed, "java/lang/Long", "longValue", "()J", ()).await?, 12); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getIndex", "()I", ()) + .await?, + 4 + ); let prefix_pattern = JavaLangString::from_rust_string(&jvm, "'\u{1f600}'0x").await?; let _: () = jvm - .invoke_virtual(&format, "applyPattern", "(Ljava/lang/String;)V", (prefix_pattern,)) + .invoke_virtual( + &format, + "java/text/DecimalFormat", + "applyPattern", + "(Ljava/lang/String;)V", + (prefix_pattern,), + ) .await?; let source = JavaLangString::from_rust_string(&jvm, "\u{1f600}12y").await?; let position: ClassInstanceRef = jvm.new_class("java/text/ParsePosition", "(I)V", (0,)).await?.into(); let parsed: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/DecimalFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;", (source, position.clone()), ) .await?; assert!(parsed.is_null()); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getErrorIndex", "()I", ()).await?, 4); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getErrorIndex", "()I", ()) + .await?, + 4 + ); let suffix_pattern = JavaLangString::from_rust_string(&jvm, "0;0-").await?; let _: () = jvm - .invoke_virtual(&format, "applyPattern", "(Ljava/lang/String;)V", (suffix_pattern,)) + .invoke_virtual( + &format, + "java/text/DecimalFormat", + "applyPattern", + "(Ljava/lang/String;)V", + (suffix_pattern,), + ) .await?; let source = JavaLangString::from_rust_string(&jvm, "12-").await?; let position: ClassInstanceRef = jvm.new_class("java/text/ParsePosition", "(I)V", (0,)).await?.into(); let parsed: ClassInstanceRef = jvm .invoke_virtual( &format, + "java/text/DecimalFormat", "parse", "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;", (source, position.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&parsed, "longValue", "()J", ()).await?, -12); - assert_eq!(jvm.invoke_virtual::<_, i32>(&position, "getIndex", "()I", ()).await?, 3); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&parsed, "java/lang/Long", "longValue", "()J", ()).await?, + -12 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&position, "java/text/ParsePosition", "getIndex", "()I", ()) + .await?, + 3 + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/util/jar/test_attributes.rs b/java_runtime/tests/classes/java/util/jar/test_attributes.rs index 4d9ca5a2..eb9145da 100644 --- a/java_runtime/tests/classes/java/util/jar/test_attributes.rs +++ b/java_runtime/tests/classes/java/util/jar/test_attributes.rs @@ -19,6 +19,7 @@ async fn test_attribute_get_set() -> Result<()> { let old: ClassInstanceRef = jvm .invoke_virtual( &attributes, + &attributes.class_definition().name(), "putValue", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (name.clone(), value), @@ -27,7 +28,13 @@ async fn test_attribute_get_set() -> Result<()> { assert!(old.is_null()); let value = jvm - .invoke_virtual(&attributes, "getValue", "(Ljava/lang/String;)Ljava/lang/String;", (name,)) + .invoke_virtual( + &attributes, + &attributes.class_definition().name(), + "getValue", + "(Ljava/lang/String;)Ljava/lang/String;", + (name,), + ) .await?; let value = JavaLangString::to_rust_string(&jvm, &value).await?; diff --git a/java_runtime/tests/classes/java/util/jar/test_jar_file.rs b/java_runtime/tests/classes/java/util/jar/test_jar_file.rs index ff043a80..a4d9f2df 100644 --- a/java_runtime/tests/classes/java/util/jar/test_jar_file.rs +++ b/java_runtime/tests/classes/java/util/jar/test_jar_file.rs @@ -13,15 +13,29 @@ async fn test_jar_manifest() -> Result<()> { let file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (name,)).await?; let jar = jvm.new_class("java/util/jar/JarFile", "(Ljava/io/File;)V", (file,)).await?; - let manifest = jvm.invoke_virtual(&jar, "getManifest", "()Ljava/util/jar/Manifest;", ()).await?; + let manifest = jvm + .invoke_virtual(&jar, &jar.class_definition().name(), "getManifest", "()Ljava/util/jar/Manifest;", ()) + .await?; let main_attributes = jvm - .invoke_virtual(&manifest, "getMainAttributes", "()Ljava/util/jar/Attributes;", ()) + .invoke_virtual( + &manifest, + &manifest.class_definition().name(), + "getMainAttributes", + "()Ljava/util/jar/Attributes;", + (), + ) .await?; let key = JavaLangString::from_rust_string(&jvm, "Main-Class").await?; let value = jvm - .invoke_virtual(&main_attributes, "getValue", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &main_attributes, + &main_attributes.class_definition().name(), + "getValue", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "JarTest"); @@ -38,36 +52,56 @@ async fn test_entries() -> Result<()> { let name = JavaLangString::from_rust_string(&jvm, "test.jar").await?; let jar = jvm.new_class("java/util/jar/JarFile", "(Ljava/lang/String;)V", (name,)).await?; - let entries = jvm.invoke_virtual(&jar, "entries", "()Ljava/util/Enumeration;", ()).await?; + let entries = jvm + .invoke_virtual(&jar, &jar.class_definition().name(), "entries", "()Ljava/util/Enumeration;", ()) + .await?; - let has_more_elements: bool = jvm.invoke_virtual(&entries, "hasMoreElements", "()Z", ()).await?; + let has_more_elements: bool = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "hasMoreElements", "()Z", ()) + .await?; assert!(has_more_elements); - let next_element: ClassInstanceRef = jvm.invoke_virtual(&entries, "nextElement", "()Ljava/lang/Object;", ()).await?; + let next_element: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; let name = jvm.get_field(&next_element, "name", "Ljava/lang/String;").await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "META-INF/"); - let has_more_elements: bool = jvm.invoke_virtual(&entries, "hasMoreElements", "()Z", ()).await?; + let has_more_elements: bool = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "hasMoreElements", "()Z", ()) + .await?; assert!(has_more_elements); - let next_element: ClassInstanceRef = jvm.invoke_virtual(&entries, "nextElement", "()Ljava/lang/Object;", ()).await?; + let next_element: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; let name = jvm.get_field(&next_element, "name", "Ljava/lang/String;").await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "META-INF/MANIFEST.MF"); - let has_more_elements: bool = jvm.invoke_virtual(&entries, "hasMoreElements", "()Z", ()).await?; + let has_more_elements: bool = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "hasMoreElements", "()Z", ()) + .await?; assert!(has_more_elements); - let next_element: ClassInstanceRef = jvm.invoke_virtual(&entries, "nextElement", "()Ljava/lang/Object;", ()).await?; + let next_element: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; let name = jvm.get_field(&next_element, "name", "Ljava/lang/String;").await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "JarTest.class"); - let has_more_elements: bool = jvm.invoke_virtual(&entries, "hasMoreElements", "()Z", ()).await?; + let has_more_elements: bool = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "hasMoreElements", "()Z", ()) + .await?; assert!(has_more_elements); - let next_element: ClassInstanceRef = jvm.invoke_virtual(&entries, "nextElement", "()Ljava/lang/Object;", ()).await?; + let next_element: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; let name = jvm.get_field(&next_element, "name", "Ljava/lang/String;").await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "test.txt"); - let has_more_elements: bool = jvm.invoke_virtual(&entries, "hasMoreElements", "()Z", ()).await?; + let has_more_elements: bool = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "hasMoreElements", "()Z", ()) + .await?; assert!(!has_more_elements); Ok(()) diff --git a/java_runtime/tests/classes/java/util/jar/test_manifest.rs b/java_runtime/tests/classes/java/util/jar/test_manifest.rs index f2493fe3..bc5dcbe7 100644 --- a/java_runtime/tests/classes/java/util/jar/test_manifest.rs +++ b/java_runtime/tests/classes/java/util/jar/test_manifest.rs @@ -16,12 +16,24 @@ async fn test_manifest_parsing() -> Result<()> { .await?; let main_attributes = jvm - .invoke_virtual(&manifest, "getMainAttributes", "()Ljava/util/jar/Attributes;", ()) + .invoke_virtual( + &manifest, + &manifest.class_definition().name(), + "getMainAttributes", + "()Ljava/util/jar/Attributes;", + (), + ) .await?; let key = JavaLangString::from_rust_string(&jvm, "Main-Class").await?; let value = jvm - .invoke_virtual(&main_attributes, "getValue", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &main_attributes, + &main_attributes.class_definition().name(), + "getValue", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "test"); diff --git a/java_runtime/tests/classes/java/util/logging/test_handlers.rs b/java_runtime/tests/classes/java/util/logging/test_handlers.rs index 977c4b93..fbae0851 100644 --- a/java_runtime/tests/classes/java/util/logging/test_handlers.rs +++ b/java_runtime/tests/classes/java/util/logging/test_handlers.rs @@ -115,13 +115,20 @@ async fn formatter_substitutes_message_parameters() -> Result<()> { jvm.store_array(&mut parameters, 10, [JavaLangString::from_rust_string(&jvm, "parameter ten").await?]) .await?; let _: () = jvm - .invoke_virtual(&record, "setParameters", "([Ljava/lang/Object;)V", (parameters,)) + .invoke_virtual( + &record, + "java/util/logging/LogRecord", + "setParameters", + "([Ljava/lang/Object;)V", + (parameters,), + ) .await?; let formatter: ClassInstanceRef = jvm.new_class("java/util/logging/SimpleFormatter", "()V", ()).await?.into(); let formatted: ClassInstanceRef = jvm .invoke_virtual( &formatter, + "java/util/logging/SimpleFormatter", "formatMessage", "(Ljava/util/logging/LogRecord;)Ljava/lang/String;", (record,), @@ -161,11 +168,19 @@ async fn simple_formatter_includes_throwable_stack_trace() -> Result<()> { ) .await?; jvm.put_field(&mut thrown, "stackTrace", "[Ljava/lang/String;", stack_trace).await?; - let _: () = jvm.invoke_virtual(&record, "setThrown", "(Ljava/lang/Throwable;)V", (thrown,)).await?; + let _: () = jvm + .invoke_virtual(&record, "java/util/logging/LogRecord", "setThrown", "(Ljava/lang/Throwable;)V", (thrown,)) + .await?; let formatter: ClassInstanceRef = jvm.new_class("java/util/logging/SimpleFormatter", "()V", ()).await?.into(); let formatted: ClassInstanceRef = jvm - .invoke_virtual(&formatter, "format", "(Ljava/util/logging/LogRecord;)Ljava/lang/String;", (record,)) + .invoke_virtual( + &formatter, + "java/util/logging/SimpleFormatter", + "format", + "(Ljava/util/logging/LogRecord;)Ljava/lang/String;", + (record,), + ) .await?; let formatted = JavaLangString::to_rust_string(&jvm, &formatted).await?; assert!(formatted.contains("java.lang.RuntimeException: boom")); @@ -199,7 +214,13 @@ async fn stream_handler_reports_output_failures_without_propagating_them() -> Re .into(); let _: () = jvm - .invoke_virtual(&handler, "publish", "(Ljava/util/logging/LogRecord;)V", (record,)) + .invoke_virtual( + &handler, + "java/util/logging/StreamHandler", + "publish", + "(Ljava/util/logging/LogRecord;)V", + (record,), + ) .await?; Ok(()) } @@ -221,12 +242,24 @@ async fn stream_handler_applies_level_and_custom_filter_before_writing() -> Resu .get_static_field("java/util/logging/Level", "WARNING", "Ljava/util/logging/Level;") .await?; let _: () = jvm - .invoke_virtual(&handler, "setLevel", "(Ljava/util/logging/Level;)V", (warning.clone(),)) + .invoke_virtual( + &handler, + "java/util/logging/StreamHandler", + "setLevel", + "(Ljava/util/logging/Level;)V", + (warning.clone(),), + ) .await?; let denied: ClassInstanceRef = jvm.new_class("ConfigurableLoggingFilter", "(Z)V", (false,)).await?.into(); let _: () = jvm - .invoke_virtual(&handler, "setFilter", "(Ljava/util/logging/Filter;)V", (denied,)) + .invoke_virtual( + &handler, + "java/util/logging/StreamHandler", + "setFilter", + "(Ljava/util/logging/Filter;)V", + (denied,), + ) .await?; let denied_record: ClassInstanceRef = jvm .new_class( @@ -237,12 +270,24 @@ async fn stream_handler_applies_level_and_custom_filter_before_writing() -> Resu .await? .into(); let _: () = jvm - .invoke_virtual(&handler, "publish", "(Ljava/util/logging/LogRecord;)V", (denied_record,)) + .invoke_virtual( + &handler, + "java/util/logging/StreamHandler", + "publish", + "(Ljava/util/logging/LogRecord;)V", + (denied_record,), + ) .await?; let allowed: ClassInstanceRef = jvm.new_class("ConfigurableLoggingFilter", "(Z)V", (true,)).await?.into(); let _: () = jvm - .invoke_virtual(&handler, "setFilter", "(Ljava/util/logging/Filter;)V", (allowed,)) + .invoke_virtual( + &handler, + "java/util/logging/StreamHandler", + "setFilter", + "(Ljava/util/logging/Filter;)V", + (allowed,), + ) .await?; let allowed_record: ClassInstanceRef = jvm .new_class( @@ -253,11 +298,21 @@ async fn stream_handler_applies_level_and_custom_filter_before_writing() -> Resu .await? .into(); let _: () = jvm - .invoke_virtual(&handler, "publish", "(Ljava/util/logging/LogRecord;)V", (allowed_record,)) + .invoke_virtual( + &handler, + "java/util/logging/StreamHandler", + "publish", + "(Ljava/util/logging/LogRecord;)V", + (allowed_record,), + ) + .await?; + let _: () = jvm + .invoke_virtual(&handler, "java/util/logging/StreamHandler", "flush", "()V", ()) .await?; - let _: () = jvm.invoke_virtual(&handler, "flush", "()V", ()).await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&output, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toString", "()Ljava/lang/String;", ()) + .await?; let text = JavaLangString::to_rust_string(&jvm, &text).await?; assert!(!text.contains("denied")); assert!(text.contains("allowed")); diff --git a/java_runtime/tests/classes/java/util/logging/test_level.rs b/java_runtime/tests/classes/java/util/logging/test_level.rs index 1c21e1a5..d35156f3 100644 --- a/java_runtime/tests/classes/java/util/logging/test_level.rs +++ b/java_runtime/tests/classes/java/util/logging/test_level.rs @@ -91,7 +91,11 @@ async fn standard_levels_have_java_values_and_parse_names_or_numbers() -> Result ("ALL", i32::MIN), ] { let level: ClassInstanceRef = jvm.get_static_field("java/util/logging/Level", name, "Ljava/util/logging/Level;").await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&level, "intValue", "()I", ()).await?, value); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&level, "java/util/logging/Level", "intValue", "()I", ()) + .await?, + value + ); let parsed: ClassInstanceRef = jvm .invoke_static( "java/util/logging/Level", @@ -112,8 +116,14 @@ async fn standard_levels_have_java_values_and_parse_names_or_numbers() -> Result (custom_name,), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&custom, "intValue", "()I", ()).await?, 42); - let name: ClassInstanceRef = jvm.invoke_virtual(&custom, "getName", "()Ljava/lang/String;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&custom, "java/util/logging/Level", "intValue", "()I", ()) + .await?, + 42 + ); + let name: ClassInstanceRef = jvm + .invoke_virtual(&custom, "java/util/logging/Level", "getName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "42"); Ok(()) diff --git a/java_runtime/tests/classes/java/util/logging/test_log_record.rs b/java_runtime/tests/classes/java/util/logging/test_log_record.rs index 226e605f..3178fa16 100644 --- a/java_runtime/tests/classes/java/util/logging/test_log_record.rs +++ b/java_runtime/tests/classes/java/util/logging/test_log_record.rs @@ -29,10 +29,18 @@ async fn log_record_initializes_event_metadata_and_round_trips_properties() -> R .await? .into(); - let first_sequence: i64 = jvm.invoke_virtual(&first, "getSequenceNumber", "()J", ()).await?; - let second_sequence: i64 = jvm.invoke_virtual(&second, "getSequenceNumber", "()J", ()).await?; + let first_sequence: i64 = jvm + .invoke_virtual(&first, "java/util/logging/LogRecord", "getSequenceNumber", "()J", ()) + .await?; + let second_sequence: i64 = jvm + .invoke_virtual(&second, "java/util/logging/LogRecord", "getSequenceNumber", "()J", ()) + .await?; assert_eq!(second_sequence, first_sequence + 1); - assert!(jvm.invoke_virtual::<_, i64>(&first, "getMillis", "()J", ()).await? > 0); + assert!( + jvm.invoke_virtual::<_, i64>(&first, "java/util/logging/LogRecord", "getMillis", "()J", ()) + .await? + > 0 + ); let logger_name = JavaLangString::from_rust_string(&jvm, "app").await?; let source_class = JavaLangString::from_rust_string(&jvm, "App").await?; @@ -41,25 +49,57 @@ async fn log_record_initializes_event_metadata_and_round_trips_properties() -> R let parameter = JavaLangString::from_rust_string(&jvm, "value").await?; jvm.store_array(&mut parameters, 0, [parameter]).await?; let _: () = jvm - .invoke_virtual(&first, "setLoggerName", "(Ljava/lang/String;)V", (logger_name,)) + .invoke_virtual( + &first, + "java/util/logging/LogRecord", + "setLoggerName", + "(Ljava/lang/String;)V", + (logger_name,), + ) .await?; let _: () = jvm - .invoke_virtual(&first, "setSourceClassName", "(Ljava/lang/String;)V", (source_class,)) + .invoke_virtual( + &first, + "java/util/logging/LogRecord", + "setSourceClassName", + "(Ljava/lang/String;)V", + (source_class,), + ) .await?; let _: () = jvm - .invoke_virtual(&first, "setSourceMethodName", "(Ljava/lang/String;)V", (source_method,)) + .invoke_virtual( + &first, + "java/util/logging/LogRecord", + "setSourceMethodName", + "(Ljava/lang/String;)V", + (source_method,), + ) .await?; let _: () = jvm - .invoke_virtual(&first, "setParameters", "([Ljava/lang/Object;)V", (parameters,)) + .invoke_virtual( + &first, + "java/util/logging/LogRecord", + "setParameters", + "([Ljava/lang/Object;)V", + (parameters,), + ) .await?; - let actual: ClassInstanceRef = jvm.invoke_virtual(&first, "getLoggerName", "()Ljava/lang/String;", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&first, "java/util/logging/LogRecord", "getLoggerName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, "app"); - let actual: ClassInstanceRef = jvm.invoke_virtual(&first, "getSourceClassName", "()Ljava/lang/String;", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&first, "java/util/logging/LogRecord", "getSourceClassName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, "App"); - let actual: ClassInstanceRef = jvm.invoke_virtual(&first, "getSourceMethodName", "()Ljava/lang/String;", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&first, "java/util/logging/LogRecord", "getSourceMethodName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, "run"); - let actual: ClassInstanceRef> = jvm.invoke_virtual(&first, "getParameters", "()[Ljava/lang/Object;", ()).await?; + let actual: ClassInstanceRef> = jvm + .invoke_virtual(&first, "java/util/logging/LogRecord", "getParameters", "()[Ljava/lang/Object;", ()) + .await?; assert_eq!(jvm.array_length(&actual).await?, 1); Ok(()) diff --git a/java_runtime/tests/classes/java/util/logging/test_logger.rs b/java_runtime/tests/classes/java/util/logging/test_logger.rs index 0ea7f7f2..e755a188 100644 --- a/java_runtime/tests/classes/java/util/logging/test_logger.rs +++ b/java_runtime/tests/classes/java/util/logging/test_logger.rs @@ -37,7 +37,9 @@ async fn named_loggers_are_reused_and_reparented_when_ancestor_is_added_late() - (parent_name,), ) .await?; - let actual: ClassInstanceRef = jvm.invoke_virtual(&child, "getParent", "()Ljava/util/logging/Logger;", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&child, "java/util/logging/Logger", "getParent", "()Ljava/util/logging/Logger;", ()) + .await?; assert_eq!(actual.identity(), parent.identity()); Ok(()) } @@ -64,7 +66,9 @@ async fn existing_logger_preserves_and_validates_resource_bundle_name() -> Resul ) .await?; assert_eq!(logger.identity(), bundled.identity()); - let actual: ClassInstanceRef = jvm.invoke_virtual(&logger, "getResourceBundleName", "()Ljava/lang/String;", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&logger, "java/util/logging/Logger", "getResourceBundleName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, "messages"); let same: ClassInstanceRef = jvm @@ -103,7 +107,9 @@ async fn logger_inherits_levels_and_publishes_convenience_methods() -> Result<() (JavaLangString::from_rust_string(&jvm, "output.test").await?,), ) .await?; - let _: () = jvm.invoke_virtual(&logger, "setUseParentHandlers", "(Z)V", (false,)).await?; + let _: () = jvm + .invoke_virtual(&logger, "java/util/logging/Logger", "setUseParentHandlers", "(Z)V", (false,)) + .await?; let output: ClassInstanceRef = jvm.new_class("java/io/ByteArrayOutputStream", "()V", ()).await?.into(); let formatter: ClassInstanceRef = jvm.new_class("java/util/logging/SimpleFormatter", "()V", ()).await?.into(); @@ -116,18 +122,31 @@ async fn logger_inherits_levels_and_publishes_convenience_methods() -> Result<() .await? .into(); let _: () = jvm - .invoke_virtual(&logger, "addHandler", "(Ljava/util/logging/Handler;)V", (handler.clone(),)) + .invoke_virtual( + &logger, + "java/util/logging/Logger", + "addHandler", + "(Ljava/util/logging/Handler;)V", + (handler.clone(),), + ) .await?; let warning: ClassInstanceRef = jvm .get_static_field("java/util/logging/Level", "WARNING", "Ljava/util/logging/Level;") .await?; let _: () = jvm - .invoke_virtual(&logger, "setLevel", "(Ljava/util/logging/Level;)V", (warning,)) + .invoke_virtual( + &logger, + "java/util/logging/Logger", + "setLevel", + "(Ljava/util/logging/Level;)V", + (warning,), + ) .await?; let _: () = jvm .invoke_virtual( &logger, + "java/util/logging/Logger", "info", "(Ljava/lang/String;)V", (JavaLangString::from_rust_string(&jvm, "hidden").await?,), @@ -136,14 +155,17 @@ async fn logger_inherits_levels_and_publishes_convenience_methods() -> Result<() let _: () = jvm .invoke_virtual( &logger, + "java/util/logging/Logger", "warning", "(Ljava/lang/String;)V", (JavaLangString::from_rust_string(&jvm, "visible").await?,), ) .await?; - let _: () = jvm.invoke_virtual(&handler, "flush", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&handler, "java/util/logging/Handler", "flush", "()V", ()).await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&output, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toString", "()Ljava/lang/String;", ()) + .await?; let text = JavaLangString::to_rust_string(&jvm, &text).await?; assert!(!text.contains("hidden")); assert!(text.contains("visible")); @@ -169,7 +191,9 @@ async fn logger_publishes_to_parent_handlers_until_propagation_is_disabled() -> (JavaLangString::from_rust_string(&jvm, "propagation.child").await?,), ) .await?; - let _: () = jvm.invoke_virtual(&parent, "setUseParentHandlers", "(Z)V", (false,)).await?; + let _: () = jvm + .invoke_virtual(&parent, "java/util/logging/Logger", "setUseParentHandlers", "(Z)V", (false,)) + .await?; let output: ClassInstanceRef = jvm.new_class("java/io/ByteArrayOutputStream", "()V", ()).await?.into(); let formatter: ClassInstanceRef = jvm.new_class("java/util/logging/SimpleFormatter", "()V", ()).await?.into(); @@ -182,32 +206,46 @@ async fn logger_publishes_to_parent_handlers_until_propagation_is_disabled() -> .await? .into(); let _: () = jvm - .invoke_virtual(&parent, "addHandler", "(Ljava/util/logging/Handler;)V", (handler.clone(),)) + .invoke_virtual( + &parent, + "java/util/logging/Logger", + "addHandler", + "(Ljava/util/logging/Handler;)V", + (handler.clone(),), + ) .await?; let _: () = jvm .invoke_virtual( &child, + "java/util/logging/Logger", "info", "(Ljava/lang/String;)V", (JavaLangString::from_rust_string(&jvm, "from child").await?,), ) .await?; - let _: () = jvm.invoke_virtual(&handler, "flush", "()V", ()).await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&output, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm.invoke_virtual(&handler, "java/util/logging/Handler", "flush", "()V", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toString", "()Ljava/lang/String;", ()) + .await?; assert!(JavaLangString::to_rust_string(&jvm, &text).await?.contains("from child")); - let _: () = jvm.invoke_virtual(&child, "setUseParentHandlers", "(Z)V", (false,)).await?; + let _: () = jvm + .invoke_virtual(&child, "java/util/logging/Logger", "setUseParentHandlers", "(Z)V", (false,)) + .await?; let _: () = jvm .invoke_virtual( &child, + "java/util/logging/Logger", "info", "(Ljava/lang/String;)V", (JavaLangString::from_rust_string(&jvm, "not propagated").await?,), ) .await?; - let _: () = jvm.invoke_virtual(&handler, "flush", "()V", ()).await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&output, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm.invoke_virtual(&handler, "java/util/logging/Handler", "flush", "()V", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toString", "()Ljava/lang/String;", ()) + .await?; assert!(!JavaLangString::to_rust_string(&jvm, &text).await?.contains("not propagated")); Ok(()) } @@ -240,27 +278,42 @@ async fn log_manager_reset_removes_handlers_and_restores_levels() -> Result<()> .get_static_field("java/util/logging/Level", "SEVERE", "Ljava/util/logging/Level;") .await?; let _: () = jvm - .invoke_virtual(&logger, "addHandler", "(Ljava/util/logging/Handler;)V", (handler,)) + .invoke_virtual( + &logger, + "java/util/logging/Logger", + "addHandler", + "(Ljava/util/logging/Handler;)V", + (handler,), + ) + .await?; + let _: () = jvm + .invoke_virtual(&logger, "java/util/logging/Logger", "setLevel", "(Ljava/util/logging/Level;)V", (severe,)) .await?; - let _: () = jvm.invoke_virtual(&logger, "setLevel", "(Ljava/util/logging/Level;)V", (severe,)).await?; - let _: () = jvm.invoke_virtual(&manager, "reset", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&manager, "java/util/logging/LogManager", "reset", "()V", ()).await?; - let handlers: ClassInstanceRef> = jvm.invoke_virtual(&logger, "getHandlers", "()[Ljava/util/logging/Handler;", ()).await?; + let handlers: ClassInstanceRef> = jvm + .invoke_virtual(&logger, "java/util/logging/Logger", "getHandlers", "()[Ljava/util/logging/Handler;", ()) + .await?; assert_eq!(jvm.array_length(&handlers).await?, 0); - let level: ClassInstanceRef = jvm.invoke_virtual(&logger, "getLevel", "()Ljava/util/logging/Level;", ()).await?; + let level: ClassInstanceRef = jvm + .invoke_virtual(&logger, "java/util/logging/Logger", "getLevel", "()Ljava/util/logging/Level;", ()) + .await?; assert!(level.is_null()); let root: ClassInstanceRef = jvm .invoke_virtual( &manager, + "java/util/logging/LogManager", "getLogger", "(Ljava/lang/String;)Ljava/util/logging/Logger;", (JavaLangString::from_rust_string(&jvm, "").await?,), ) .await?; - let root_level: ClassInstanceRef = jvm.invoke_virtual(&root, "getLevel", "()Ljava/util/logging/Level;", ()).await?; - let value: i32 = jvm.invoke_virtual(&root_level, "intValue", "()I", ()).await?; + let root_level: ClassInstanceRef = jvm + .invoke_virtual(&root, "java/util/logging/Logger", "getLevel", "()Ljava/util/logging/Level;", ()) + .await?; + let value: i32 = jvm.invoke_virtual(&root_level, "java/util/logging/Level", "intValue", "()I", ()).await?; assert_eq!(value, 800); Ok(()) } @@ -276,7 +329,13 @@ async fn global_logger_and_manager_initialize_in_either_entry_order() -> Result< .await?; let name = JavaLangString::from_rust_string(&jvm, "global").await?; let registered: ClassInstanceRef = jvm - .invoke_virtual(&manager, "getLogger", "(Ljava/lang/String;)Ljava/util/logging/Logger;", (name,)) + .invoke_virtual( + &manager, + "java/util/logging/LogManager", + "getLogger", + "(Ljava/lang/String;)Ljava/util/logging/Logger;", + (name,), + ) .await?; assert_eq!(global.identity(), registered.identity()); @@ -289,7 +348,13 @@ async fn global_logger_and_manager_initialize_in_either_entry_order() -> Result< .await?; let name = JavaLangString::from_rust_string(&jvm, "global").await?; let registered: ClassInstanceRef = jvm - .invoke_virtual(&manager, "getLogger", "(Ljava/lang/String;)Ljava/util/logging/Logger;", (name,)) + .invoke_virtual( + &manager, + "java/util/logging/LogManager", + "getLogger", + "(Ljava/lang/String;)Ljava/util/logging/Logger;", + (name,), + ) .await?; assert_eq!(global.identity(), registered.identity()); Ok(()) diff --git a/java_runtime/tests/classes/java/util/regex/test_matcher.rs b/java_runtime/tests/classes/java/util/regex/test_matcher.rs index e5ed0165..f53a195d 100644 --- a/java_runtime/tests/classes/java/util/regex/test_matcher.rs +++ b/java_runtime/tests/classes/java/util/regex/test_matcher.rs @@ -179,18 +179,32 @@ async fn full_match_reselects_alternatives_without_shifting_capture_groups() -> .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "ab").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "matches", "()Z", ()).await?); - let group: ClassInstanceRef = jvm.invoke_virtual(&matcher, "group", "()Ljava/lang/String;", ()).await?; + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "matches", "()Z", ()) + .await? + ); + let group: ClassInstanceRef = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "group", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &group).await?, "ab"); assert_eq!( - jvm.invoke_virtual::<_, i32>(&matcher, "groupCount", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "groupCount", "()I", ()) + .await?, expected_group_count ); if expected_group_count == 1 { - let group: ClassInstanceRef = jvm.invoke_virtual(&matcher, "group", "(I)Ljava/lang/String;", (1,)).await?; + let group: ClassInstanceRef = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "group", "(I)Ljava/lang/String;", (1,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &group).await?, "ab"); } } @@ -206,10 +220,21 @@ async fn full_match_reselects_alternatives_without_shifting_capture_groups() -> .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "ab").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) + .await?; + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "lookingAt", "()Z", ()) + .await? + ); + let group: ClassInstanceRef = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "group", "()Ljava/lang/String;", ()) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "lookingAt", "()Z", ()).await?); - let group: ClassInstanceRef = jvm.invoke_virtual(&matcher, "group", "()Ljava/lang/String;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &group).await?, "a"); Ok(()) @@ -231,9 +256,18 @@ async fn comments_mode_allows_a_terminal_comment_in_full_and_prefix_matches() -> for method in ["matches", "lookingAt"] { let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "a").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, method, "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", method, "()Z", ()) + .await? + ); } Ok(()) @@ -253,9 +287,18 @@ async fn full_match_preserves_inline_comment_modes() -> Result<()> { .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "a").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "matches", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "matches", "()Z", ()) + .await? + ); let source = JavaLangString::from_rust_string(&jvm, "(?-x)a # trailing").await?; let pattern: ClassInstanceRef = jvm @@ -268,9 +311,18 @@ async fn full_match_preserves_inline_comment_modes() -> Result<()> { .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "a # trailing").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "matches", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "matches", "()Z", ()) + .await? + ); Ok(()) } @@ -289,15 +341,40 @@ async fn captures_report_unmatched_empty_and_utf16_ranges() -> Result<()> { .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "bbb").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) + .await?; + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "matches", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "groupCount", "()I", ()) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "(I)I", (1,)) + .await?, + -1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "(I)I", (1,)) + .await?, + -1 + ); + let unmatched: ClassInstanceRef = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "group", "(I)Ljava/lang/String;", (1,)) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "matches", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "groupCount", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "(I)I", (1,)).await?, -1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "end", "(I)I", (1,)).await?, -1); - let unmatched: ClassInstanceRef = jvm.invoke_virtual(&matcher, "group", "(I)Ljava/lang/String;", (1,)).await?; assert!(unmatched.is_null()); - let group: ClassInstanceRef = jvm.invoke_virtual(&matcher, "group", "(I)Ljava/lang/String;", (2,)).await?; + let group: ClassInstanceRef = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "group", "(I)Ljava/lang/String;", (2,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &group).await?, "bbb"); let source = JavaLangString::from_rust_string(&jvm, "(a*)").await?; @@ -311,12 +388,31 @@ async fn captures_report_unmatched_empty_and_utf16_ranges() -> Result<()> { .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "b").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) + .await?; + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "(I)I", (1,)) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "(I)I", (1,)) + .await?, + 0 + ); + let empty: ClassInstanceRef = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "group", "(I)Ljava/lang/String;", (1,)) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "(I)I", (1,)).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "end", "(I)I", (1,)).await?, 0); - let empty: ClassInstanceRef = jvm.invoke_virtual(&matcher, "group", "(I)Ljava/lang/String;", (1,)).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &empty).await?, ""); let source = JavaLangString::from_rust_string(&jvm, "(😀)(한)").await?; @@ -330,27 +426,42 @@ async fn captures_report_unmatched_empty_and_utf16_ranges() -> Result<()> { .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "A😀한B").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); assert_eq!( ( - jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&matcher, "end", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "()I", ()) + .await?, ), (1, 4) ); assert_eq!( ( - jvm.invoke_virtual::<_, i32>(&matcher, "start", "(I)I", (1,)).await?, - jvm.invoke_virtual::<_, i32>(&matcher, "end", "(I)I", (1,)).await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "(I)I", (1,)) + .await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "(I)I", (1,)) + .await?, ), (1, 3) ); assert_eq!( ( - jvm.invoke_virtual::<_, i32>(&matcher, "start", "(I)I", (2,)).await?, - jvm.invoke_virtual::<_, i32>(&matcher, "end", "(I)I", (2,)).await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "(I)I", (2,)) + .await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "(I)I", (2,)) + .await?, ), (3, 4) ); @@ -372,35 +483,54 @@ async fn failed_or_missing_matches_enforce_state_before_group_bounds() -> Result .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "baa").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - let result: Result> = jvm.invoke_virtual(&matcher, "group", "(I)Ljava/lang/String;", (-1,)).await; + let result: Result> = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "group", "(I)Ljava/lang/String;", (-1,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("group before a match must throw"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalStateException")); - assert!(!jvm.invoke_virtual::<_, bool>(&matcher, "matches", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "matches", "()Z", ()) + .await? + ); for (name, descriptor) in [("start", "()I"), ("end", "()I")] { - let result: Result = jvm.invoke_virtual(&matcher, name, descriptor, ()).await; + let result: Result = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", name, descriptor, ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("{name} after a failed match must throw"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalStateException")); } - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); for group in [-1, 1] { - let result: Result = jvm.invoke_virtual(&matcher, "start", "(I)I", (group,)).await; + let result: Result = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "start", "(I)I", (group,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("out-of-range group must throw"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); } - assert!(!jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); - let result: Result> = jvm.invoke_virtual(&matcher, "group", "()Ljava/lang/String;", ()).await; + assert!( + !jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + let result: Result> = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "group", "()Ljava/lang/String;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("group after find failure must throw"); }; @@ -424,20 +554,37 @@ async fn find_advances_after_zero_width_matches_and_stops_after_the_end() -> Res .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, input).await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; for range in expected { - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); assert_eq!( ( - jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&matcher, "end", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "()I", ()) + .await?, ), range ); } - assert!(!jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); - assert!(!jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); } let source = JavaLangString::from_rust_string(&jvm, "a*").await?; @@ -451,18 +598,35 @@ async fn find_advances_after_zero_width_matches_and_stops_after_the_end() -> Res .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "a").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "matches", "()Z", ()).await?); - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "matches", "()Z", ()) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); assert_eq!( ( - jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&matcher, "end", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "()I", ()) + .await?, ), (1, 1) ); - assert!(!jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); Ok(()) } @@ -481,18 +645,32 @@ async fn find_at_input_length_matches_the_end_anchor() -> Result<()> { .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "ab").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "(I)Z", (2,)).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "(I)Z", (2,)) + .await? + ); assert_eq!( ( - jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&matcher, "end", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "()I", ()) + .await?, ), (2, 2) ); - assert!(!jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); Ok(()) } @@ -519,10 +697,16 @@ async fn invalid_find_start_is_checked_before_creating_an_input_snapshot() -> Re ) .await?; let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - let result: Result = jvm.invoke_virtual(&matcher, "find", "(I)Z", (-1,)).await; + let result: Result = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "find", "(I)Z", (-1,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("negative find start must throw"); }; @@ -530,7 +714,7 @@ async fn invalid_find_start_is_checked_before_creating_an_input_snapshot() -> Re assert_eq!(jvm.get_field::(&sequence, "lengthCalls", "I").await?, 0); assert_eq!(jvm.get_field::(&sequence, "snapshotCalls", "I").await?, 0); - let result: Result = jvm.invoke_virtual(&matcher, "find", "(I)Z", (2,)).await; + let result: Result = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "find", "(I)Z", (2,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("find start beyond the input length must throw"); }; @@ -564,13 +748,26 @@ async fn valid_find_start_resets_state_before_creating_an_input_snapshot() -> Re ) .await?; let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, 0); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 0 + ); jvm.put_field(&mut sequence, "failSnapshot", "Z", true).await?; - let result: Result = jvm.invoke_virtual(&matcher, "find", "(I)Z", (0,)).await; + let result: Result = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "find", "(I)Z", (0,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("snapshot failure must be observable"); }; @@ -578,7 +775,7 @@ async fn valid_find_start_resets_state_before_creating_an_input_snapshot() -> Re assert_eq!(jvm.get_field::(&sequence, "lengthCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&sequence, "snapshotCalls", "I").await?, 2); - let result: Result = jvm.invoke_virtual(&matcher, "start", "()I", ()).await; + let result: Result = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "start", "()I", ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("valid find(start) must invalidate the previous match before searching"); }; @@ -603,16 +800,34 @@ async fn find_continues_from_the_prefix_end_after_successful_looking_at() -> Res .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "abca").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "lookingAt", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "end", "()I", ()).await?, 1); - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "lookingAt", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "()I", ()) + .await?, + 1 + ); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); assert_eq!( ( - jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&matcher, "end", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "()I", ()) + .await?, ), (3, 4) ); @@ -634,42 +849,85 @@ async fn find_start_and_reset_preserve_or_replace_state_as_specified() -> Result .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "baac").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, 1); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 1 + ); for invalid in [-1, 5] { - let result: Result = jvm.invoke_virtual(&matcher, "find", "(I)Z", (invalid,)).await; + let result: Result = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "find", "(I)Z", (invalid,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("invalid find start must throw"); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 1 + ); } - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "(I)Z", (2,)).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, 2); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "(I)Z", (2,)) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 2 + ); let null: ClassInstanceRef = None.into(); let result: Result> = jvm - .invoke_virtual(&matcher, "reset", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (null,)) + .invoke_virtual( + &matcher, + "java/util/regex/Matcher", + "reset", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (null,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("reset(null) must throw"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 2 + ); - let reset: ClassInstanceRef = jvm.invoke_virtual(&matcher, "reset", "()Ljava/util/regex/Matcher;", ()).await?; + let reset: ClassInstanceRef = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "reset", "()Ljava/util/regex/Matcher;", ()) + .await?; assert_eq!(reset.identity(), matcher.identity()); - let result: Result = jvm.invoke_virtual(&matcher, "start", "()I", ()).await; + let result: Result = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "start", "()I", ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("reset must invalidate the previous match"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalStateException")); - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, 1); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 1 + ); Ok(()) } @@ -689,23 +947,55 @@ async fn reset_accepts_string_buffer_snapshots_and_matchers_keep_independent_sta let first_input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "x!x").await?.into(); let second_input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "!x").await?.into(); let first: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (first_input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (first_input,), + ) .await?; let second: ClassInstanceRef = jvm .invoke_virtual( &pattern, + "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (second_input,), ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&first, "find", "()Z", ()).await?); - assert!(jvm.invoke_virtual::<_, bool>(&second, "find", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "start", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "start", "()I", ()).await?, 1); - assert!(jvm.invoke_virtual::<_, bool>(&first, "find", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "start", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "start", "()I", ()).await?, 1); + assert!( + jvm.invoke_virtual::<_, bool>(&first, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&second, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 1 + ); + assert!( + jvm.invoke_virtual::<_, bool>(&first, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 1 + ); let value = JavaLangString::from_rust_string(&jvm, "xy").await?; let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (value,)).await?.into(); @@ -713,16 +1003,28 @@ async fn reset_accepts_string_buffer_snapshots_and_matchers_keep_independent_sta let reset: ClassInstanceRef = jvm .invoke_virtual( &second, + "java/util/regex/Matcher", "reset", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (buffer_as_sequence,), ) .await?; assert_eq!(reset.identity(), second.identity()); - assert!(jvm.invoke_virtual::<_, bool>(&second, "find", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "start", "()I", ()).await?, 0); - let _: () = jvm.invoke_virtual(&buffer, "setCharAt", "(IC)V", (0, 'y' as JavaChar)).await?; - let parent: ClassInstanceRef = jvm.invoke_virtual(&second, "pattern", "()Ljava/util/regex/Pattern;", ()).await?; + assert!( + jvm.invoke_virtual::<_, bool>(&second, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 0 + ); + let _: () = jvm + .invoke_virtual(&buffer, "java/lang/StringBuffer", "setCharAt", "(IC)V", (0, 'y' as JavaChar)) + .await?; + let parent: ClassInstanceRef = jvm + .invoke_virtual(&second, "java/util/regex/Matcher", "pattern", "()Ljava/util/regex/Pattern;", ()) + .await?; assert_eq!(parent.identity(), pattern.identity()); Ok(()) diff --git a/java_runtime/tests/classes/java/util/regex/test_pattern.rs b/java_runtime/tests/classes/java/util/regex/test_pattern.rs index 0bb8de55..8756aec9 100644 --- a/java_runtime/tests/classes/java/util/regex/test_pattern.rs +++ b/java_runtime/tests/classes/java/util/regex/test_pattern.rs @@ -129,9 +129,15 @@ async fn compile_preserves_the_source_and_valid_flags() -> Result<()> { (source.clone(),), ) .await?; - let actual: ClassInstanceRef = jvm.invoke_virtual(&pattern, "pattern", "()Ljava/lang/String;", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual(&pattern, "java/util/regex/Pattern", "pattern", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, "a+b"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&pattern, "flags", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&pattern, "java/util/regex/Pattern", "flags", "()I", ()) + .await?, + 0 + ); let source = JavaLangString::from_rust_string(&jvm, "a").await?; let pattern: ClassInstanceRef = jvm @@ -142,7 +148,11 @@ async fn compile_preserves_the_source_and_valid_flags() -> Result<()> { (source, 0xef), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&pattern, "flags", "()I", ()).await?, 0xef); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&pattern, "java/util/regex/Pattern", "flags", "()I", ()) + .await?, + 0xef + ); Ok(()) } @@ -159,15 +169,28 @@ async fn compile_passes_modern_regex_syntax_through_without_translation() -> Res (source.clone(),), ) .await?; - let preserved: ClassInstanceRef = jvm.invoke_virtual(&pattern, "pattern", "()Ljava/lang/String;", ()).await?; + let preserved: ClassInstanceRef = jvm + .invoke_virtual(&pattern, "java/util/regex/Pattern", "pattern", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &preserved).await?, r"(?Pa+)"); let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "aaa").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) + .await?; + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "matches", "()Z", ()) + .await? + ); + let group: ClassInstanceRef = jvm + .invoke_virtual(&matcher, "java/util/regex/Matcher", "group", "(I)Ljava/lang/String;", (1,)) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "matches", "()Z", ()).await?); - let group: ClassInstanceRef = jvm.invoke_virtual(&matcher, "group", "(I)Ljava/lang/String;", (1,)).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &group).await?, "aaa"); Ok(()) @@ -240,10 +263,30 @@ async fn compile_reports_rust_regex_errors_as_pattern_syntax_exception() -> Resu }; assert!(jvm.is_instance(&*exception, "java/util/regex/PatternSyntaxException")); let exception: ClassInstanceRef = exception.into(); - let actual: ClassInstanceRef = jvm.invoke_virtual(&exception, "getPattern", "()Ljava/lang/String;", ()).await?; + let actual: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getPattern", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual).await?, source); - assert_eq!(jvm.invoke_virtual::<_, i32>(&exception, "getIndex", "()I", ()).await?, -1); - let description: ClassInstanceRef = jvm.invoke_virtual(&exception, "getDescription", "()Ljava/lang/String;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&exception, "java/util/regex/PatternSyntaxException", "getIndex", "()I", ()) + .await?, + -1 + ); + let description: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getDescription", + "()Ljava/lang/String;", + (), + ) + .await?; assert!(!JavaLangString::to_rust_string(&jvm, &description).await?.is_empty()); } @@ -270,9 +313,19 @@ async fn pattern_flags_control_rust_regex_matching() -> Result<()> { .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, input).await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, bool>(&matcher, "matches", "()Z", ()).await?, expected); + assert_eq!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "matches", "()Z", ()) + .await?, + expected + ); } let source = JavaLangString::from_rust_string(&jvm, "^b$").await?; @@ -286,11 +339,28 @@ async fn pattern_flags_control_rust_regex_matching() -> Result<()> { .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "a\nb\nc").await?.into(); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "end", "()I", ()).await?, 3); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "end", "()I", ()) + .await?, + 3 + ); Ok(()) } @@ -322,6 +392,7 @@ async fn static_matches_and_matcher_reject_null_inputs() -> Result<()> { let result: Result> = jvm .invoke_virtual( &pattern, + "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (null_input.clone(),), diff --git a/java_runtime/tests/classes/java/util/regex/test_pattern_syntax_exception.rs b/java_runtime/tests/classes/java/util/regex/test_pattern_syntax_exception.rs index 5cab10c7..7742741d 100644 --- a/java_runtime/tests/classes/java/util/regex/test_pattern_syntax_exception.rs +++ b/java_runtime/tests/classes/java/util/regex/test_pattern_syntax_exception.rs @@ -80,13 +80,41 @@ async fn pattern_syntax_exception_formats_index_and_caret_with_the_initial_line_ .await? .into(); - let actual_description: ClassInstanceRef = jvm.invoke_virtual(&exception, "getDescription", "()Ljava/lang/String;", ()).await?; + let actual_description: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getDescription", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual_description).await?, "Unclosed group"); - let actual_pattern: ClassInstanceRef = jvm.invoke_virtual(&exception, "getPattern", "()Ljava/lang/String;", ()).await?; + let actual_pattern: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getPattern", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &actual_pattern).await?, "a("); - assert_eq!(jvm.invoke_virtual::<_, i32>(&exception, "getIndex", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&exception, "java/util/regex/PatternSyntaxException", "getIndex", "()I", ()) + .await?, + 1 + ); - let message: ClassInstanceRef = jvm.invoke_virtual(&exception, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getMessage", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, "Unclosed group near index 1|a(| ^"); let changed_separator = JavaLangString::from_rust_string(&jvm, "~").await?; @@ -98,7 +126,15 @@ async fn pattern_syntax_exception_formats_index_and_caret_with_the_initial_line_ (key, changed_separator), ) .await?; - let message: ClassInstanceRef = jvm.invoke_virtual(&exception, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getMessage", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, "Unclosed group near index 1|a(| ^"); Ok(()) @@ -127,11 +163,35 @@ async fn pattern_syntax_exception_preserves_nulls_and_keeps_java_14_caret_format ) .await? .into(); - let description: ClassInstanceRef = jvm.invoke_virtual(&exception, "getDescription", "()Ljava/lang/String;", ()).await?; + let description: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getDescription", + "()Ljava/lang/String;", + (), + ) + .await?; assert!(description.is_null()); - let pattern: ClassInstanceRef = jvm.invoke_virtual(&exception, "getPattern", "()Ljava/lang/String;", ()).await?; + let pattern: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getPattern", + "()Ljava/lang/String;", + (), + ) + .await?; assert!(pattern.is_null()); - let message: ClassInstanceRef = jvm.invoke_virtual(&exception, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getMessage", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, "null\nnull"); let description = JavaLangString::from_rust_string(&jvm, "Bad pattern").await?; @@ -144,7 +204,15 @@ async fn pattern_syntax_exception_preserves_nulls_and_keeps_java_14_caret_format ) .await? .into(); - let message: ClassInstanceRef = jvm.invoke_virtual(&exception, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getMessage", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!( JavaLangString::to_rust_string(&jvm, &message).await?, "Bad pattern near index 3\nabc\n ^" @@ -160,7 +228,15 @@ async fn pattern_syntax_exception_preserves_nulls_and_keeps_java_14_caret_format ) .await? .into(); - let message: ClassInstanceRef = jvm.invoke_virtual(&exception, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual( + &exception, + "java/util/regex/PatternSyntaxException", + "getMessage", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!( JavaLangString::to_rust_string(&jvm, &message).await?, "Missing pattern near index 2\nnull\n ^" diff --git a/java_runtime/tests/classes/java/util/regex/test_replacement.rs b/java_runtime/tests/classes/java/util/regex/test_replacement.rs index 2ac1d3ca..9681ec32 100644 --- a/java_runtime/tests/classes/java/util/regex/test_replacement.rs +++ b/java_runtime/tests/classes/java/util/regex/test_replacement.rs @@ -21,12 +21,20 @@ async fn new_matcher(jvm: &Jvm, source: &str, input: &str) -> Result = JavaLangString::from_rust_string(jvm, input).await?.into(); - jvm.invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) - .await + jvm.invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) + .await } async fn buffer_text(jvm: &Jvm, buffer: &ClassInstanceRef) -> Result { - let value: ClassInstanceRef = jvm.invoke_virtual(buffer, "toString", "()Ljava/lang/String;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(buffer, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", ()) + .await?; JavaLangString::to_rust_string(jvm, &value).await } @@ -60,10 +68,14 @@ async fn append_replacement_expands_groups_and_preserves_unmatched_input() -> Re let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?.into(); let replacement = JavaLangString::from_rust_string(&jvm, "<$1>").await?; - while jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await? { + while jvm + .invoke_virtual::<_, bool>(&matcher, &matcher.class_definition().name(), "find", "()Z", ()) + .await? + { let returned: ClassInstanceRef = jvm .invoke_virtual( &matcher, + &matcher.class_definition().name(), "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (buffer.clone(), replacement.clone()), @@ -74,6 +86,7 @@ async fn append_replacement_expands_groups_and_preserves_unmatched_input() -> Re let returned: ClassInstanceRef = jvm .invoke_virtual( &matcher, + &matcher.class_definition().name(), "appendTail", "(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;", (buffer.clone(),), @@ -100,7 +113,13 @@ async fn replacement_parser_handles_group_numbers_unmatched_groups_and_escapes() let matcher = new_matcher(&jvm, source, input).await?; let replacement = JavaLangString::from_rust_string(&jvm, replacement).await?; let result: ClassInstanceRef = jvm - .invoke_virtual(&matcher, "replaceFirst", "(Ljava/lang/String;)Ljava/lang/String;", (replacement,)) + .invoke_virtual( + &matcher, + &matcher.class_definition().name(), + "replaceFirst", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, expected); } @@ -108,7 +127,13 @@ async fn replacement_parser_handles_group_numbers_unmatched_groups_and_escapes() let matcher = new_matcher(&jvm, "😀", "A😀B").await?; let replacement = JavaLangString::from_rust_string(&jvm, "한").await?; let result: ClassInstanceRef = jvm - .invoke_virtual(&matcher, "replaceFirst", "(Ljava/lang/String;)Ljava/lang/String;", (replacement,)) + .invoke_virtual( + &matcher, + &matcher.class_definition().name(), + "replaceFirst", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "A한B"); @@ -121,7 +146,13 @@ async fn replace_all_advances_through_zero_width_matches_without_losing_input() let matcher = new_matcher(&jvm, "", "ab").await?; let replacement = JavaLangString::from_rust_string(&jvm, "-").await?; let result: ClassInstanceRef = jvm - .invoke_virtual(&matcher, "replaceAll", "(Ljava/lang/String;)Ljava/lang/String;", (replacement,)) + .invoke_virtual( + &matcher, + &matcher.class_definition().name(), + "replaceAll", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "-a-b-"); @@ -144,11 +175,23 @@ async fn replacement_accepts_string_buffer_as_a_char_sequence() -> Result<()> { let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (value,)).await?.into(); let input: ClassInstanceRef = ClassInstanceRef::new(buffer.clone().instance); let matcher: ClassInstanceRef = jvm - .invoke_virtual(&pattern, "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (input,)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "matcher", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (input,), + ) .await?; let replacement = JavaLangString::from_rust_string(&jvm, "x").await?; let result: ClassInstanceRef = jvm - .invoke_virtual(&matcher, "replaceAll", "(Ljava/lang/String;)Ljava/lang/String;", (replacement,)) + .invoke_virtual( + &matcher, + "java/util/regex/Matcher", + "replaceAll", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "xbx"); @@ -159,7 +202,10 @@ async fn replacement_accepts_string_buffer_as_a_char_sequence() -> Result<()> { async fn malformed_replacements_leave_the_buffer_and_append_position_retryable() -> Result<()> { let jvm = test_jvm().await?; let matcher = new_matcher(&jvm, "a", "aba").await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); let seed = JavaLangString::from_rust_string(&jvm, "seed").await?; let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (seed,)).await?.into(); @@ -173,6 +219,7 @@ async fn malformed_replacements_leave_the_buffer_and_append_position_retryable() let result: Result> = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (buffer.clone(), replacement), @@ -189,6 +236,7 @@ async fn malformed_replacements_leave_the_buffer_and_append_position_retryable() let result: Result> = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (buffer.clone(), null_replacement), @@ -205,6 +253,7 @@ async fn malformed_replacements_leave_the_buffer_and_append_position_retryable() let result: Result> = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (null_buffer.clone(), malformed), @@ -219,6 +268,7 @@ async fn malformed_replacements_leave_the_buffer_and_append_position_retryable() let result: Result> = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (null_buffer, valid.clone()), @@ -232,16 +282,21 @@ async fn malformed_replacements_leave_the_buffer_and_append_position_retryable() let _: ClassInstanceRef = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (buffer.clone(), valid), ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); let replacement = JavaLangString::from_rust_string(&jvm, "y").await?; let _: ClassInstanceRef = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (buffer.clone(), replacement), @@ -250,6 +305,7 @@ async fn malformed_replacements_leave_the_buffer_and_append_position_retryable() let _: ClassInstanceRef = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendTail", "(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;", (buffer.clone(),), @@ -269,6 +325,7 @@ async fn append_methods_enforce_state_before_arguments_and_append_tail_needs_no_ let result: Result> = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (null_buffer.clone(), malformed), @@ -283,6 +340,7 @@ async fn append_methods_enforce_state_before_arguments_and_append_tail_needs_no_ let _: ClassInstanceRef = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendTail", "(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;", (before.clone(),), @@ -293,6 +351,7 @@ async fn append_methods_enforce_state_before_arguments_and_append_tail_needs_no_ let result: Result> = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendTail", "(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;", (null_buffer.clone(),), @@ -303,12 +362,19 @@ async fn append_methods_enforce_state_before_arguments_and_append_tail_needs_no_ }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); - assert!(!jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); let valid = JavaLangString::from_rust_string(&jvm, "x").await?; let result: Result> = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (null_buffer.clone(), valid), @@ -322,6 +388,7 @@ async fn append_methods_enforce_state_before_arguments_and_append_tail_needs_no_ let result: Result> = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendTail", "(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;", (null_buffer,), @@ -342,10 +409,16 @@ async fn replace_all_and_first_preserve_their_documented_final_match_state() -> let all = new_matcher(&jvm, "a", "aba").await?; let result: ClassInstanceRef = jvm - .invoke_virtual(&all, "replaceAll", "(Ljava/lang/String;)Ljava/lang/String;", (replacement.clone(),)) + .invoke_virtual( + &all, + &all.class_definition().name(), + "replaceAll", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "xbx"); - let state: Result = jvm.invoke_virtual(&all, "start", "()I", ()).await; + let state: Result = jvm.invoke_virtual(&all, &all.class_definition().name(), "start", "()I", ()).await; let Err(JavaError::JavaException(exception)) = state else { panic!("replaceAll must end with an invalid match state"); }; @@ -353,11 +426,25 @@ async fn replace_all_and_first_preserve_their_documented_final_match_state() -> let first = new_matcher(&jvm, "a", "aba").await?; let result: ClassInstanceRef = jvm - .invoke_virtual(&first, "replaceFirst", "(Ljava/lang/String;)Ljava/lang/String;", (replacement,)) + .invoke_virtual( + &first, + &first.class_definition().name(), + "replaceFirst", + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "xba"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "start", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "end", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "start", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "end", "()I", ()) + .await?, + 1 + ); Ok(()) } @@ -369,7 +456,13 @@ async fn replace_without_a_match_does_not_read_a_null_replacement() -> Result<() let matcher = new_matcher(&jvm, "z", "abc").await?; let replacement: ClassInstanceRef = None.into(); let result: ClassInstanceRef = jvm - .invoke_virtual(&matcher, method, "(Ljava/lang/String;)Ljava/lang/String;", (replacement,)) + .invoke_virtual( + &matcher, + "java/util/regex/Matcher", + method, + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "abc"); } @@ -378,7 +471,13 @@ async fn replace_without_a_match_does_not_read_a_null_replacement() -> Result<() let matcher = new_matcher(&jvm, "a", "abc").await?; let replacement: ClassInstanceRef = None.into(); let result: Result> = jvm - .invoke_virtual(&matcher, method, "(Ljava/lang/String;)Ljava/lang/String;", (replacement,)) + .invoke_virtual( + &matcher, + "java/util/regex/Matcher", + method, + "(Ljava/lang/String;)Ljava/lang/String;", + (replacement,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{method} with a matching pattern and null replacement must throw"); @@ -394,18 +493,22 @@ async fn invalid_find_and_reset_leave_search_and_append_positions_usable() -> Re let jvm = test_jvm().await?; let matcher = new_matcher(&jvm, "a", "aXa").await?; let buffer: ClassInstanceRef = jvm.new_class("java/lang/StringBuffer", "()V", ()).await?.into(); - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); let first = JavaLangString::from_rust_string(&jvm, "x").await?; let _: ClassInstanceRef = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (buffer.clone(), first), ) .await?; - let result: Result = jvm.invoke_virtual(&matcher, "find", "(I)Z", (-1,)).await; + let result: Result = jvm.invoke_virtual(&matcher, "java/util/regex/Matcher", "find", "(I)Z", (-1,)).await; let Err(JavaError::JavaException(exception)) = result else { panic!("find(-1) must throw"); }; @@ -413,19 +516,33 @@ async fn invalid_find_and_reset_leave_search_and_append_positions_usable() -> Re let null: ClassInstanceRef = None.into(); let result: Result> = jvm - .invoke_virtual(&matcher, "reset", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", (null,)) + .invoke_virtual( + &matcher, + "java/util/regex/Matcher", + "reset", + "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", + (null,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("reset(null) must throw"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - assert!(jvm.invoke_virtual::<_, bool>(&matcher, "find", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&matcher, "start", "()I", ()).await?, 2); + assert!( + jvm.invoke_virtual::<_, bool>(&matcher, "java/util/regex/Matcher", "find", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&matcher, "java/util/regex/Matcher", "start", "()I", ()) + .await?, + 2 + ); let second = JavaLangString::from_rust_string(&jvm, "y").await?; let _: ClassInstanceRef = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendReplacement", "(Ljava/lang/StringBuffer;Ljava/lang/String;)Ljava/util/regex/Matcher;", (buffer.clone(), second), @@ -434,6 +551,7 @@ async fn invalid_find_and_reset_leave_search_and_append_positions_usable() -> Re let _: ClassInstanceRef = jvm .invoke_virtual( &matcher, + "java/util/regex/Matcher", "appendTail", "(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;", (buffer.clone(),), diff --git a/java_runtime/tests/classes/java/util/regex/test_split.rs b/java_runtime/tests/classes/java/util/regex/test_split.rs index 581ec6c4..f7e67ca8 100644 --- a/java_runtime/tests/classes/java/util/regex/test_split.rs +++ b/java_runtime/tests/classes/java/util/regex/test_split.rs @@ -24,7 +24,13 @@ async fn split(jvm: &Jvm, input: &str, source: &str, limit: i32) -> Result = JavaLangString::from_rust_string(jvm, input).await?.into(); let values: ClassInstanceRef> = jvm - .invoke_virtual(&pattern, "split", "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", (input, limit)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", + (input, limit), + ) .await?; let mut result = Vec::new(); for value in jvm @@ -125,10 +131,22 @@ async fn split_without_limit_matches_an_explicit_zero_limit() -> Result<()> { .await?; let input: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "boo:and:foo").await?.into(); let implicit: ClassInstanceRef> = jvm - .invoke_virtual(&pattern, "split", "(Ljava/lang/CharSequence;)[Ljava/lang/String;", (input.clone(),)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;)[Ljava/lang/String;", + (input.clone(),), + ) .await?; let explicit: ClassInstanceRef> = jvm - .invoke_virtual(&pattern, "split", "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", (input, 0)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", + (input, 0), + ) .await?; let implicit = jvm @@ -164,7 +182,13 @@ async fn split_accepts_string_buffer_and_returns_a_java_string_array() -> Result let buffer = jvm.new_class("java/lang/StringBuffer", "(Ljava/lang/String;)V", (value,)).await?; let input: ClassInstanceRef = ClassInstanceRef::new(Some(buffer)); let values: ClassInstanceRef> = jvm - .invoke_virtual(&pattern, "split", "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", (input, -1)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", + (input, -1), + ) .await?; assert_eq!(values.class_definition().name(), "[Ljava/lang/String;"); @@ -194,7 +218,13 @@ async fn split_rejects_a_null_input() -> Result<()> { .await?; let input: ClassInstanceRef = None.into(); let result: Result>> = jvm - .invoke_virtual(&pattern, "split", "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", (input, 0)) + .invoke_virtual( + &pattern, + "java/util/regex/Pattern", + "split", + "(Ljava/lang/CharSequence;I)[Ljava/lang/String;", + (input, 0), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Pattern.split(null) must throw"); diff --git a/java_runtime/tests/classes/java/util/test_array_list.rs b/java_runtime/tests/classes/java/util/test_array_list.rs index d645201a..57326625 100644 --- a/java_runtime/tests/classes/java/util/test_array_list.rs +++ b/java_runtime/tests/classes/java/util/test_array_list.rs @@ -16,54 +16,108 @@ async fn test_array_list_basic_operations_and_capacity_zero() -> Result<()> { let middle = JavaLangString::from_rust_string(&jvm, "middle").await?; let replacement = JavaLangString::from_rust_string(&jvm, "replacement").await?; - let added: bool = jvm.invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (first.clone(),)).await?; + let added: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (first.clone(),), + ) + .await?; assert!(added); let element_data: ClassInstanceRef> = jvm.get_field(&array_list, "elementData", "[Ljava/lang/Object;").await?; assert!(jvm.array_length(&element_data).await? >= 1); - let _: bool = jvm.invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (second.clone(),)).await?; + let _: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (second.clone(),), + ) + .await?; let _: () = jvm - .invoke_virtual(&array_list, "add", "(ILjava/lang/Object;)V", (1, middle.clone())) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(ILjava/lang/Object;)V", + (1, middle.clone()), + ) .await?; - let size: i32 = jvm.invoke_virtual(&array_list, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 3); - let value: ClassInstanceRef = jvm.invoke_virtual(&array_list, "get", "(I)Ljava/lang/Object;", (0,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (0,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "first"); - let value: ClassInstanceRef = jvm.invoke_virtual(&array_list, "get", "(I)Ljava/lang/Object;", (1,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (1,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "middle"); let old: ClassInstanceRef = jvm - .invoke_virtual(&array_list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (1, replacement.clone())) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (1, replacement.clone()), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &old).await?, "middle"); - let removed: ClassInstanceRef = jvm.invoke_virtual(&array_list, "remove", "(I)Ljava/lang/Object;", (0,)).await?; + let removed: ClassInstanceRef = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "remove", + "(I)Ljava/lang/Object;", + (0,), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "first"); - let size: i32 = jvm.invoke_virtual(&array_list, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 2); let element_data: ClassInstanceRef> = jvm.get_field(&array_list, "elementData", "[Ljava/lang/Object;").await?; let removed_tail_slot: ClassInstanceRef = jvm.load_array(&element_data, 2, 1).await?.into_iter().next().unwrap(); assert!(removed_tail_slot.is_null()); - let array: ClassInstanceRef> = jvm.invoke_virtual(&array_list, "toArray", "()[Ljava/lang/Object;", ()).await?; + let array: ClassInstanceRef> = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; assert_eq!(jvm.array_length(&array).await?, 2); let values: Vec> = jvm.load_array(&array, 0, 2).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &values[0]).await?, "replacement"); assert_eq!(JavaLangString::to_rust_string(&jvm, &values[1]).await?, "second"); - let _: () = jvm.invoke_virtual(&array_list, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&array_list, "size", "()I", ()).await?; + let _: () = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "clear", "()V", ()) + .await?; + let size: i32 = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let is_empty: bool = jvm.invoke_virtual(&array_list, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); - let array: ClassInstanceRef> = jvm.invoke_virtual(&array_list, "toArray", "()[Ljava/lang/Object;", ()).await?; + let array: ClassInstanceRef> = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; assert_eq!(jvm.array_length(&array).await?, 0); let element_data: ClassInstanceRef> = jvm.get_field(&array_list, "elementData", "[Ljava/lang/Object;").await?; @@ -86,44 +140,112 @@ async fn test_array_list_null_equality_and_remove_object() -> Result<()> { let missing = JavaLangString::from_rust_string(&jvm, "missing").await?; let _: bool = jvm - .invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (stored,), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (tail.clone(),), + ) .await?; - let _: bool = jvm.invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (stored,)).await?; - let _: bool = jvm.invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (tail.clone(),)).await?; let index: i32 = jvm - .invoke_virtual(&array_list, "indexOf", "(Ljava/lang/Object;)I", (null_ref.clone(),)) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (null_ref.clone(),), + ) .await?; assert_eq!(index, 0); let contains: bool = jvm - .invoke_virtual(&array_list, "contains", "(Ljava/lang/Object;)Z", (equal.clone(),)) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (equal.clone(),), + ) .await?; assert!(contains); let index: i32 = jvm - .invoke_virtual(&array_list, "indexOf", "(Ljava/lang/Object;)I", (equal.clone(),)) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (equal.clone(),), + ) .await?; assert_eq!(index, 1); let removed: bool = jvm - .invoke_virtual(&array_list, "remove", "(Ljava/lang/Object;)Z", (equal.clone(),)) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (equal.clone(),), + ) .await?; assert!(removed); - let index: i32 = jvm.invoke_virtual(&array_list, "indexOf", "(Ljava/lang/Object;)I", (equal,)).await?; + let index: i32 = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (equal,), + ) + .await?; assert_eq!(index, -1); - let removed: bool = jvm.invoke_virtual(&array_list, "remove", "(Ljava/lang/Object;)Z", (missing,)).await?; + let removed: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (missing,), + ) + .await?; assert!(!removed); - let size: i32 = jvm.invoke_virtual(&array_list, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 2); - let value: ClassInstanceRef = jvm.invoke_virtual(&array_list, "get", "(I)Ljava/lang/Object;", (0,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (0,)) + .await?; assert!(value.is_null()); - let value: ClassInstanceRef = jvm.invoke_virtual(&array_list, "get", "(I)Ljava/lang/Object;", (1,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (1,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "tail"); Ok(()) @@ -152,23 +274,51 @@ async fn test_array_list_assignability_and_interface_style_calls() -> Result<()> let value = JavaLangString::from_rust_string(&jvm, "interface-style").await?; let equal_value = JavaLangString::from_rust_string(&jvm, "interface-style").await?; - let _: bool = jvm.invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (value,), + ) + .await?; - let size: i32 = jvm.invoke_virtual(&array_list, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 1); let contains: bool = jvm - .invoke_virtual(&array_list, "contains", "(Ljava/lang/Object;)Z", (equal_value.clone(),)) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (equal_value.clone(),), + ) .await?; assert!(contains); - let value: ClassInstanceRef = jvm.invoke_virtual(&array_list, "get", "(I)Ljava/lang/Object;", (0,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (0,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "interface-style"); - let removed: bool = jvm.invoke_virtual(&array_list, "remove", "(Ljava/lang/Object;)Z", (equal_value,)).await?; + let removed: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (equal_value,), + ) + .await?; assert!(removed); - let is_empty: bool = jvm.invoke_virtual(&array_list, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); Ok(()) @@ -182,51 +332,121 @@ async fn test_array_list_itr_is_live_and_remove_writes_through() -> Result<()> { let first = JavaLangString::from_rust_string(&jvm, "first").await?; let second = JavaLangString::from_rust_string(&jvm, "second").await?; - let _: bool = jvm.invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (first,)).await?; - let _: bool = jvm.invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (second,)).await?; + let _: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (first,), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (second,), + ) + .await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&array_list, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; assert!(jvm.is_instance(&**iterator, "java/util/Iterator")); let third = JavaLangString::from_rust_string(&jvm, "third").await?; - let _: bool = jvm.invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (third,)).await?; + let _: bool = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (third,), + ) + .await?; - let has_next: bool = jvm.invoke_virtual(&iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; assert!(has_next); - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "first"); - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "second"); - let has_next: bool = jvm.invoke_virtual(&iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; assert!(has_next); - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "third"); - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&array_list, "size", "()I", ()).await?, 2); + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&array_list, &array_list.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); - let result: Result> = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; assert!(jvm.is_instance(&*exception, "java/util/NoSuchElementException")); - let result: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let result: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalStateException")); let empty_array_list = jvm.new_class("java/util/ArrayList", "()V", ()).await?; - let empty_iterator: ClassInstanceRef = jvm.invoke_virtual(&empty_array_list, "iterator", "()Ljava/util/Iterator;", ()).await?; - let has_next: bool = jvm.invoke_virtual(&empty_iterator, "hasNext", "()Z", ()).await?; + let empty_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &empty_array_list, + &empty_array_list.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let has_next: bool = jvm + .invoke_virtual(&empty_iterator, &empty_iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; assert!(!has_next); - let result: Result> = jvm.invoke_virtual(&empty_iterator, "next", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual( + &empty_iterator, + &empty_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; @@ -247,7 +467,9 @@ async fn test_array_list_bounds_and_negative_capacity() -> Result<()> { let array_list = jvm.new_class("java/util/ArrayList", "()V", ()).await?; - let result: Result> = jvm.invoke_virtual(&array_list, "get", "(I)Ljava/lang/Object;", (0,)).await; + let result: Result> = jvm + .invoke_virtual(&array_list, &array_list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (0,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; @@ -255,7 +477,13 @@ async fn test_array_list_bounds_and_negative_capacity() -> Result<()> { let element = JavaLangString::from_rust_string(&jvm, "element").await?; let result: Result<()> = jvm - .invoke_virtual(&array_list, "add", "(ILjava/lang/Object;)V", (1, element.clone())) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(ILjava/lang/Object;)V", + (1, element.clone()), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); @@ -263,7 +491,13 @@ async fn test_array_list_bounds_and_negative_capacity() -> Result<()> { assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); let result: Result<()> = jvm - .invoke_virtual(&array_list, "add", "(ILjava/lang/Object;)V", (-1, element.clone())) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(ILjava/lang/Object;)V", + (-1, element.clone()), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); @@ -271,24 +505,52 @@ async fn test_array_list_bounds_and_negative_capacity() -> Result<()> { assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); let _: bool = jvm - .invoke_virtual(&array_list, "add", "(Ljava/lang/Object;)Z", (element.clone(),)) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element.clone(),), + ) .await?; let result: Result> = jvm - .invoke_virtual(&array_list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (1, element.clone())) + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (1, element.clone()), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let result: Result> = jvm.invoke_virtual(&array_list, "remove", "(I)Ljava/lang/Object;", (-1,)).await; + let result: Result> = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "remove", + "(I)Ljava/lang/Object;", + (-1,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let result: Result> = jvm.invoke_virtual(&array_list, "remove", "(I)Ljava/lang/Object;", (1,)).await; + let result: Result> = jvm + .invoke_virtual( + &array_list, + &array_list.class_definition().name(), + "remove", + "(I)Ljava/lang/Object;", + (1,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; diff --git a/java_runtime/tests/classes/java/util/test_arrays.rs b/java_runtime/tests/classes/java/util/test_arrays.rs index c4975eb0..f8b67de3 100644 --- a/java_runtime/tests/classes/java/util/test_arrays.rs +++ b/java_runtime/tests/classes/java/util/test_arrays.rs @@ -744,20 +744,38 @@ async fn test_arr_08_as_list_is_live_fixed_size_and_uses_abstract_list_contracts .await?; assert!(jvm.is_instance(list.as_ref(), "java/util/List")); assert!(jvm.is_instance(list.as_ref(), "java/io/Serializable")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); jvm.store_array(&mut array, 0, core::iter::once(third.clone())).await?; - let from_list: ClassInstanceRef = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (0,)).await?; + let from_list: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (0,)) + .await?; assert_eq!(from_list.identity(), third.identity()); let previous: ClassInstanceRef = jvm - .invoke_virtual(&list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (1, first.clone())) + .invoke_virtual( + &list, + &list.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (1, first.clone()), + ) .await?; assert_eq!(previous.identity(), second.identity()); let from_array = jvm.load_array::>(&array, 1, 1).await?.remove(0); assert_eq!(from_array.identity(), first.identity()); let incompatible = jvm.new_class("java/lang/Object", "()V", ()).await?; let result: Result> = jvm - .invoke_virtual(&list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (1, incompatible)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (1, incompatible), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("array-backed list set must preserve the component type"); @@ -768,46 +786,86 @@ async fn test_arr_08_as_list_is_live_fixed_size_and_uses_abstract_list_contracts first.identity() ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&list, "indexOf", "(Ljava/lang/Object;)I", (first.clone(),)) - .await?, + jvm.invoke_virtual::<_, i32>( + &list, + &list.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (first.clone(),) + ) + .await?, 1 ); assert!( - jvm.invoke_virtual::<_, bool>(&list, "contains", "(Ljava/lang/Object;)Z", (third.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (third.clone(),) + ) + .await? ); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "()Ljava/util/ListIterator;", ()).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let _: () = jvm.invoke_virtual(&iterator, "set", "(Ljava/lang/Object;)V", (second.clone(),)).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "listIterator", "()Ljava/util/ListIterator;", ()) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let _: () = jvm + .invoke_virtual( + &iterator, + &iterator.class_definition().name(), + "set", + "(Ljava/lang/Object;)V", + (second.clone(),), + ) + .await?; assert_eq!( jvm.load_array::>(&array, 0, 1).await?.remove(0).identity(), second.identity() ); - let result: Result<()> = jvm.invoke_virtual(&iterator, "add", "(Ljava/lang/Object;)V", (third.clone(),)).await; + let result: Result<()> = jvm + .invoke_virtual( + &iterator, + &iterator.class_definition().name(), + "add", + "(Ljava/lang/Object;)V", + (third.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("list iterator add must fail"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let result: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let result: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("list iterator remove must fail"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let result: Result = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (third.clone(),)).await; + let result: Result = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (third.clone(),)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("fixed list add must fail"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let result: Result = jvm.invoke_virtual(&list, "remove", "(Ljava/lang/Object;)Z", (first,)).await; + let result: Result = jvm + .invoke_virtual(&list, &list.class_definition().name(), "remove", "(Ljava/lang/Object;)Z", (first,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("fixed list remove must fail"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let result: Result<()> = jvm.invoke_virtual(&list, "clear", "()V", ()).await; + let result: Result<()> = jvm.invoke_virtual(&list, &list.class_definition().name(), "clear", "()V", ()).await; let Err(JavaError::JavaException(exception)) = result else { panic!("fixed list clear must fail"); }; @@ -815,7 +873,13 @@ async fn test_arr_08_as_list_is_live_fixed_size_and_uses_abstract_list_contracts let typed: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/String;", 0).await?.into(); let copied: ClassInstanceRef> = jvm - .invoke_virtual(&list, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (typed,)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (typed,), + ) .await?; assert_eq!(copied.class_definition().name(), "[Ljava/lang/String;"); assert_eq!(jvm.array_length(&copied).await?, 2); @@ -1505,47 +1569,115 @@ async fn test_arr_08_array_list_bulk_mutation_noop_and_unsupported_paths() -> Re let empty = jvm.new_class("java/util/ArrayList", "()V", ()).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&list, "addAll", "(Ljava/util/Collection;)Z", (empty.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "addAll", + "(Ljava/util/Collection;)Z", + (empty.clone(),) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&list, "addAll", "(ILjava/util/Collection;)Z", (1, empty.clone())) - .await? + !jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "addAll", + "(ILjava/util/Collection;)Z", + (1, empty.clone()) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&list, "removeAll", "(Ljava/util/Collection;)Z", (empty.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "removeAll", + "(Ljava/util/Collection;)Z", + (empty.clone(),) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&list, "retainAll", "(Ljava/util/Collection;)Z", (list.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "retainAll", + "(Ljava/util/Collection;)Z", + (list.clone(),) + ) + .await? ); let absent_collection = jvm.new_class("java/util/ArrayList", "()V", ()).await?; - let _: bool = jvm.invoke_virtual(&absent_collection, "add", "(Ljava/lang/Object;)Z", (absent,)).await?; + let _: bool = jvm + .invoke_virtual( + &absent_collection, + &absent_collection.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (absent,), + ) + .await?; assert!( - !jvm.invoke_virtual::<_, bool>(&list, "removeAll", "(Ljava/util/Collection;)Z", (absent_collection,),) - .await? + !jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "removeAll", + "(Ljava/util/Collection;)Z", + (absent_collection,), + ) + .await? ); let all = jvm.new_class("java/util/ArrayList", "()V", ()).await?; - let _: bool = jvm.invoke_virtual(&all, "add", "(Ljava/lang/Object;)Z", (first.clone(),)).await?; - let _: bool = jvm.invoke_virtual(&all, "add", "(Ljava/lang/Object;)Z", (second.clone(),)).await?; + let _: bool = jvm + .invoke_virtual(&all, &all.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (first.clone(),)) + .await?; + let _: bool = jvm + .invoke_virtual(&all, &all.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (second.clone(),)) + .await?; assert!( - !jvm.invoke_virtual::<_, bool>(&list, "retainAll", "(Ljava/util/Collection;)Z", (all,)) + !jvm.invoke_virtual::<_, bool>(&list, &list.class_definition().name(), "retainAll", "(Ljava/util/Collection;)Z", (all,)) .await? ); let non_empty = jvm.new_class("java/util/ArrayList", "()V", ()).await?; - let _: bool = jvm.invoke_virtual(&non_empty, "add", "(Ljava/lang/Object;)Z", (first.clone(),)).await?; + let _: bool = jvm + .invoke_virtual( + &non_empty, + &non_empty.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (first.clone(),), + ) + .await?; for result in [ - jvm.invoke_virtual::<_, bool>(&list, "addAll", "(Ljava/util/Collection;)Z", (non_empty.clone(),)) - .await, - jvm.invoke_virtual::<_, bool>(&list, "addAll", "(ILjava/util/Collection;)Z", (1, non_empty.clone())) - .await, - jvm.invoke_virtual::<_, bool>(&list, "removeAll", "(Ljava/util/Collection;)Z", (non_empty.clone(),)) - .await, - jvm.invoke_virtual::<_, bool>(&list, "retainAll", "(Ljava/util/Collection;)Z", (empty,)) + jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "addAll", + "(Ljava/util/Collection;)Z", + (non_empty.clone(),), + ) + .await, + jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "addAll", + "(ILjava/util/Collection;)Z", + (1, non_empty.clone()), + ) + .await, + jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "removeAll", + "(Ljava/util/Collection;)Z", + (non_empty.clone(),), + ) + .await, + jvm.invoke_virtual::<_, bool>(&list, &list.class_definition().name(), "retainAll", "(Ljava/util/Collection;)Z", (empty,)) .await, ] { let Err(JavaError::JavaException(exception)) = result else { @@ -1559,7 +1691,13 @@ async fn test_arr_08_array_list_bulk_mutation_noop_and_unsupported_paths() -> Re let null_collection: ClassInstanceRef = None.into(); let result: Result = jvm - .invoke_virtual(&list, "removeAll", "(Ljava/util/Collection;)Z", (null_collection,)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "removeAll", + "(Ljava/util/Collection;)Z", + (null_collection,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("bulk operation must reject a null collection"); @@ -1590,7 +1728,13 @@ async fn test_arr_08_array_list_typed_to_array_reuse_grow_termination_and_sequen .await?; let oversized_identity = oversized.identity(); let reused: ClassInstanceRef> = jvm - .invoke_virtual(&list, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (oversized,)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (oversized,), + ) .await?; assert_eq!(reused.identity(), oversized_identity); let reused_values = jvm.load_array::>(&reused, 0, 4).await?; @@ -1603,7 +1747,13 @@ async fn test_arr_08_array_list_typed_to_array_reuse_grow_termination_and_sequen jvm.store_array(&mut exact, 0, [sentinel.clone(), sentinel.clone()]).await?; let exact_identity = exact.identity(); let exact_result: ClassInstanceRef> = jvm - .invoke_virtual(&list, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (exact,)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (exact,), + ) .await?; assert_eq!(exact_result.identity(), exact_identity); let exact_values = jvm.load_array::>(&exact_result, 0, 2).await?; @@ -1614,7 +1764,13 @@ async fn test_arr_08_array_list_typed_to_array_reuse_grow_termination_and_sequen jvm.store_array(&mut small, 0, core::iter::once(sentinel.clone())).await?; let small_identity = small.identity(); let grown: ClassInstanceRef> = jvm - .invoke_virtual(&list, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (small.clone(),)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (small.clone(),), + ) .await?; assert_ne!(grown.identity(), small_identity); assert_eq!(grown.class_definition().name(), "[Ljava/lang/String;"); @@ -1626,7 +1782,13 @@ async fn test_arr_08_array_list_typed_to_array_reuse_grow_termination_and_sequen let null_destination: ClassInstanceRef> = None.into(); let result: Result>> = jvm - .invoke_virtual(&list, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (null_destination,)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (null_destination,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("typed toArray must reject null"); @@ -1651,7 +1813,13 @@ async fn test_arr_08_array_list_typed_to_array_reuse_grow_termination_and_sequen ) .await?; let result: Result>> = jvm - .invoke_virtual(&row_list, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (destination.clone(),)) + .invoke_virtual( + &row_list, + &row_list.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (destination.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("typed multidimensional toArray must reject an Object[] row"); diff --git a/java_runtime/tests/classes/java/util/test_collection_contracts.rs b/java_runtime/tests/classes/java/util/test_collection_contracts.rs index 8e0c6c8d..bde68800 100644 --- a/java_runtime/tests/classes/java/util/test_collection_contracts.rs +++ b/java_runtime/tests/classes/java/util/test_collection_contracts.rs @@ -559,37 +559,101 @@ async fn col_01_bulk_operations_handle_null_self_and_mutation_results() -> Resul let list = jvm.new_class("java/util/ArrayList", "()V", ()).await?; let first = JavaLangString::from_rust_string(&jvm, "first").await?; let second = JavaLangString::from_rust_string(&jvm, "second").await?; - let _: bool = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (first.clone(),)).await?; - let _: bool = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (second.clone(),)).await?; + let _: bool = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (first.clone(),)) + .await?; + let _: bool = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (second.clone(),)) + .await?; let contains_all: bool = jvm - .invoke_virtual(&list, "containsAll", "(Ljava/util/Collection;)Z", (list.clone(),)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "containsAll", + "(Ljava/util/Collection;)Z", + (list.clone(),), + ) .await?; assert!(contains_all); let retained: bool = jvm - .invoke_virtual(&list, "retainAll", "(Ljava/util/Collection;)Z", (list.clone(),)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "retainAll", + "(Ljava/util/Collection;)Z", + (list.clone(),), + ) .await?; assert!(!retained); - let added: bool = jvm.invoke_virtual(&list, "addAll", "(Ljava/util/Collection;)Z", (list.clone(),)).await?; + let added: bool = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "addAll", + "(Ljava/util/Collection;)Z", + (list.clone(),), + ) + .await?; assert!(added); - assert_eq!(jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?, 4); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await?, + 4 + ); let filter = jvm.new_class("java/util/HashSet", "()V", ()).await?; - let _: bool = jvm.invoke_virtual(&filter, "add", "(Ljava/lang/Object;)Z", (first.clone(),)).await?; + let _: bool = jvm + .invoke_virtual( + &filter, + &filter.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (first.clone(),), + ) + .await?; let removed: bool = jvm - .invoke_virtual(&list, "removeAll", "(Ljava/util/Collection;)Z", (filter.clone(),)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "removeAll", + "(Ljava/util/Collection;)Z", + (filter.clone(),), + ) .await?; assert!(removed); - assert_eq!(jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?, 2); - let removed_again: bool = jvm.invoke_virtual(&list, "removeAll", "(Ljava/util/Collection;)Z", (filter,)).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); + let removed_again: bool = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "removeAll", + "(Ljava/util/Collection;)Z", + (filter,), + ) + .await?; assert!(!removed_again); let removed_self: bool = jvm - .invoke_virtual(&list, "removeAll", "(Ljava/util/Collection;)Z", (list.clone(),)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "removeAll", + "(Ljava/util/Collection;)Z", + (list.clone(),), + ) .await?; assert!(removed_self); - assert_eq!(jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); let null_collection: ClassInstanceRef = None.into(); for (name, descriptor) in [ @@ -598,7 +662,9 @@ async fn col_01_bulk_operations_handle_null_self_and_mutation_results() -> Resul ("removeAll", "(Ljava/util/Collection;)Z"), ("retainAll", "(Ljava/util/Collection;)Z"), ] { - let result: Result = jvm.invoke_virtual(&list, name, descriptor, (null_collection.clone(),)).await; + let result: Result = jvm + .invoke_virtual(&list, &list.class_definition().name(), name, descriptor, (null_collection.clone(),)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{name} must reject null"); }; @@ -614,12 +680,15 @@ async fn col_02_07_09_list_defaults_and_collection_copy_constructors() -> Result let source = jvm.new_class("java/util/ArrayList", "()V", ()).await?; for value in ["a", "b", "a"] { let value = JavaLangString::from_rust_string(&jvm, value).await?; - let _: bool = jvm.invoke_virtual(&source, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual(&source, &source.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; } let index: i32 = jvm .invoke_virtual( &source, + &source.class_definition().name(), "lastIndexOf", "(Ljava/lang/Object;)I", (JavaLangString::from_rust_string(&jvm, "a").await?,), @@ -631,14 +700,25 @@ async fn col_02_07_09_list_defaults_and_collection_copy_constructors() -> Result let _: bool = jvm .invoke_virtual( &inserted, + &inserted.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (JavaLangString::from_rust_string(&jvm, "x").await?,), ) .await?; - let changed: bool = jvm.invoke_virtual(&source, "addAll", "(ILjava/util/Collection;)Z", (1, inserted)).await?; + let changed: bool = jvm + .invoke_virtual( + &source, + &source.class_definition().name(), + "addAll", + "(ILjava/util/Collection;)Z", + (1, inserted), + ) + .await?; assert!(changed); - let value: ClassInstanceRef = jvm.invoke_virtual(&source, "get", "(I)Ljava/lang/Object;", (1,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&source, &source.class_definition().name(), "get", "(I)Ljava/lang/Object;", (1,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "x"); for (class_name, descriptor) in [ @@ -648,12 +728,14 @@ async fn col_02_07_09_list_defaults_and_collection_copy_constructors() -> Result ] { let copy = jvm.new_class(class_name, descriptor, (source.clone(),)).await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(©, "size", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(©, ©.class_definition().name(), "size", "()I", ()) + .await?, if class_name.ends_with("HashSet") { 3 } else { 4 } ); assert!( jvm.invoke_virtual::<_, bool>( ©, + ©.class_definition().name(), "contains", "(Ljava/lang/Object;)Z", (JavaLangString::from_rust_string(&jvm, "x").await?,) @@ -682,6 +764,7 @@ async fn col_10_11_map_copy_and_put_all_validate_before_mutation() -> Result<()> let _: ClassInstanceRef = jvm .invoke_virtual( &source, + &source.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", ( @@ -693,21 +776,52 @@ async fn col_10_11_map_copy_and_put_all_validate_before_mutation() -> Result<()> } let hash_map = jvm.new_class("java/util/HashMap", "(Ljava/util/Map;)V", (source.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&hash_map, "size", "()I", ()).await?, 2); - let _: () = jvm.invoke_virtual(&hash_map, "putAll", "(Ljava/util/Map;)V", (hash_map.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&hash_map, "size", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); + let _: () = jvm + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (hash_map.clone(),), + ) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); let hashtable = jvm.new_class("java/util/Hashtable", "(Ljava/util/Map;)V", (source,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&hashtable, "size", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); let _: () = jvm - .invoke_virtual(&hashtable, "putAll", "(Ljava/util/Map;)V", (hashtable.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (hashtable.clone(),), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&hashtable, "size", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); let invalid = jvm.new_class("java/util/HashMap", "()V", ()).await?; let _: ClassInstanceRef = jvm .invoke_virtual( &invalid, + &invalid.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", ( @@ -720,6 +834,7 @@ async fn col_10_11_map_copy_and_put_all_validate_before_mutation() -> Result<()> let _: ClassInstanceRef = jvm .invoke_virtual( &invalid, + &invalid.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (JavaLangString::from_rust_string(&jvm, "invalid").await?, null_value), @@ -731,19 +846,38 @@ async fn col_10_11_map_copy_and_put_all_validate_before_mutation() -> Result<()> let _: ClassInstanceRef = jvm .invoke_virtual( &target, + &target.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (original_key.clone(), JavaLangString::from_rust_string(&jvm, "kept").await?), ) .await?; - let result: Result<()> = jvm.invoke_virtual(&target, "putAll", "(Ljava/util/Map;)V", (invalid.clone(),)).await; + let result: Result<()> = jvm + .invoke_virtual( + &target, + &target.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (invalid.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Hashtable.putAll must reject null values"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&target, "size", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&target, &target.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); let original: ClassInstanceRef = jvm - .invoke_virtual(&target, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (original_key,)) + .invoke_virtual( + &target, + &target.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (original_key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &original).await?, "kept"); @@ -764,6 +898,7 @@ async fn col_12_typed_to_array_reuses_grows_terminates_and_preserves_on_ase() -> let _: bool = jvm .invoke_virtual( &list, + &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (JavaLangString::from_rust_string(&jvm, value).await?,), @@ -781,7 +916,13 @@ async fn col_12_typed_to_array_reuses_grows_terminates_and_preserves_on_ase() -> .await?; let oversized_identity = oversized.identity(); let reused: ClassInstanceRef> = jvm - .invoke_virtual(&list, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (oversized,)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (oversized,), + ) .await?; assert_eq!(reused.identity(), oversized_identity); assert_eq!(reused.class_definition().name(), "[Ljava/lang/String;"); @@ -794,7 +935,13 @@ async fn col_12_typed_to_array_reuses_grows_terminates_and_preserves_on_ase() -> let small: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/String;", 1).await?.into(); let small_identity = small.identity(); let grown: ClassInstanceRef> = jvm - .invoke_virtual(&list, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (small,)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (small,), + ) .await?; assert_ne!(grown.identity(), small_identity); assert_eq!(grown.class_definition().name(), "[Ljava/lang/String;"); @@ -807,6 +954,7 @@ async fn col_12_typed_to_array_reuses_grows_terminates_and_preserves_on_ase() -> let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value.clone()), @@ -818,42 +966,80 @@ async fn col_12_typed_to_array_reuses_grows_terminates_and_preserves_on_ase() -> ("values", "()Ljava/util/Collection;", "Ljava/lang/String;", "[Ljava/lang/String;"), ("entrySet", "()Ljava/util/Set;", "Ljava/util/Map$Entry;", "[Ljava/util/Map$Entry;"), ] { - let view: ClassInstanceRef = jvm.invoke_virtual(&map, view_method, view_descriptor, ()).await?; + let view: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), view_method, view_descriptor, ()) + .await?; let destination: ClassInstanceRef> = jvm.instantiate_array(component_descriptor, 0).await?.into(); let typed: ClassInstanceRef> = jvm - .invoke_virtual(&view, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (destination,)) + .invoke_virtual( + &view, + &view.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (destination,), + ) .await?; assert_eq!(typed.class_definition().name(), expected_class); assert_eq!(jvm.array_length(&typed).await?, 1); } - let values: ClassInstanceRef = jvm.invoke_virtual(&map, "values", "()Ljava/util/Collection;", ()).await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; let removal = jvm.new_class("java/util/ArrayList", "()V", ()).await?; - let _: bool = jvm.invoke_virtual(&removal, "add", "(Ljava/lang/Object;)Z", (value,)).await?; - let changed: bool = jvm.invoke_virtual(&values, "removeAll", "(Ljava/util/Collection;)Z", (removal,)).await?; + let _: bool = jvm + .invoke_virtual(&removal, &removal.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; + let changed: bool = jvm + .invoke_virtual( + &values, + &values.class_definition().name(), + "removeAll", + "(Ljava/util/Collection;)Z", + (removal,), + ) + .await?; assert!(changed); - assert_eq!(jvm.invoke_virtual::<_, i32>(&map, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&map, &map.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, JavaLangString::from_rust_string(&jvm, "again").await?), ) .await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; let changed: bool = jvm - .invoke_virtual(&entries, "removeAll", "(Ljava/util/Collection;)Z", (entries.clone(),)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "removeAll", + "(Ljava/util/Collection;)Z", + (entries.clone(),), + ) .await?; assert!(changed); - assert_eq!(jvm.invoke_virtual::<_, i32>(&map, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&map, &map.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); } let incompatible = jvm.new_class("java/util/ArrayList", "()V", ()).await?; let _: bool = jvm .invoke_virtual( &incompatible, + &incompatible.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (JavaLangString::from_rust_string(&jvm, "compatible").await?,), @@ -862,6 +1048,7 @@ async fn col_12_typed_to_array_reuses_grows_terminates_and_preserves_on_ase() -> let _: bool = jvm .invoke_virtual( &incompatible, + &incompatible.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (jvm.new_class("java/lang/Object", "()V", ()).await?,), @@ -874,6 +1061,7 @@ async fn col_12_typed_to_array_reuses_grows_terminates_and_preserves_on_ase() -> let result: Result>> = jvm .invoke_virtual( &incompatible, + &incompatible.class_definition().name(), "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (destination.clone(),), @@ -889,7 +1077,13 @@ async fn col_12_typed_to_array_reuses_grows_terminates_and_preserves_on_ase() -> let null_array: ClassInstanceRef> = None.into(); let result: Result>> = jvm - .invoke_virtual(&list, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (null_array,)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (null_array,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("typed toArray must reject null"); @@ -912,9 +1106,15 @@ async fn col_07_08_copy_constructors_preserve_custom_snapshot_order_duplicates_a for class_name in ["java/util/ArrayList", "java/util/Vector"] { let copy = jvm.new_class(class_name, "(Ljava/util/Collection;)V", (source.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(©, "size", "()I", ()).await?, 5); + assert_eq!( + jvm.invoke_virtual::<_, i32>(©, ©.class_definition().name(), "size", "()I", ()) + .await?, + 5 + ); for (index, expected) in [Some("beta"), None, Some("alpha"), Some("beta"), None].into_iter().enumerate() { - let value: ClassInstanceRef = jvm.invoke_virtual(©, "get", "(I)Ljava/lang/Object;", (index as i32,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(©, ©.class_definition().name(), "get", "(I)Ljava/lang/Object;", (index as i32,)) + .await?; match expected { Some(expected) => assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, expected), None => assert!(value.is_null()), @@ -923,11 +1123,24 @@ async fn col_07_08_copy_constructors_preserve_custom_snapshot_order_duplicates_a } let set = jvm.new_class("java/util/HashSet", "(Ljava/util/Collection;)V", (source,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&set, "size", "()I", ()).await?, 3); - assert!(jvm.invoke_virtual::<_, bool>(&set, "contains", "(Ljava/lang/Object;)Z", (beta,)).await?); - assert!(jvm.invoke_virtual::<_, bool>(&set, "contains", "(Ljava/lang/Object;)Z", (alpha,)).await?); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&set, &set.class_definition().name(), "size", "()I", ()) + .await?, + 3 + ); + assert!( + jvm.invoke_virtual::<_, bool>(&set, &set.class_definition().name(), "contains", "(Ljava/lang/Object;)Z", (beta,)) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&set, &set.class_definition().name(), "contains", "(Ljava/lang/Object;)Z", (alpha,)) + .await? + ); let null: ClassInstanceRef = None.into(); - assert!(jvm.invoke_virtual::<_, bool>(&set, "contains", "(Ljava/lang/Object;)Z", (null,)).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&set, &set.class_definition().name(), "contains", "(Ljava/lang/Object;)Z", (null,)) + .await? + ); Ok(()) } @@ -944,6 +1157,7 @@ async fn col_10_11_put_all_preserves_equals_direction_and_hashtable_prevalidates let _: ClassInstanceRef = jvm .invoke_virtual( &target, + &target.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (stored_key.clone(), old_value), @@ -952,29 +1166,78 @@ async fn col_10_11_put_all_preserves_equals_direction_and_hashtable_prevalidates let _: ClassInstanceRef = jvm .invoke_virtual( &source, + &source.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (query_key.clone(), new_value.clone()), ) .await?; - let _: () = jvm.invoke_virtual(&target, "putAll", "(Ljava/util/Map;)V", (source.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&target, "size", "()I", ()).await?, 1); + let _: () = jvm + .invoke_virtual( + &target, + &target.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (source.clone(),), + ) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&target, &target.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); let replaced: ClassInstanceRef = jvm - .invoke_virtual(&target, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (query_key.clone(),)) + .invoke_virtual( + &target, + &target.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query_key.clone(),), + ) .await?; assert_eq!(replaced.identity(), new_value.identity()); - let target_entries: ClassInstanceRef = jvm.invoke_virtual(&target, "entrySet", "()Ljava/util/Set;", ()).await?; - let target_entries: ClassInstanceRef> = jvm.invoke_virtual(&target_entries, "toArray", "()[Ljava/lang/Object;", ()).await?; + let target_entries: ClassInstanceRef = jvm + .invoke_virtual(&target, &target.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let target_entries: ClassInstanceRef> = jvm + .invoke_virtual( + &target_entries, + &target_entries.class_definition().name(), + "toArray", + "()[Ljava/lang/Object;", + (), + ) + .await?; let target_entry: ClassInstanceRef = jvm.load_array(&target_entries, 0, 1).await?.pop().unwrap(); - let retained_key: ClassInstanceRef = jvm.invoke_virtual(&target_entry, "getKey", "()Ljava/lang/Object;", ()).await?; + let retained_key: ClassInstanceRef = jvm + .invoke_virtual( + &target_entry, + &target_entry.class_definition().name(), + "getKey", + "()Ljava/lang/Object;", + (), + ) + .await?; assert_eq!(retained_key.identity(), stored_key.identity()); let copy = jvm.new_class("java/util/HashMap", "(Ljava/util/Map;)V", (source,)).await?; - let copy_entries: ClassInstanceRef = jvm.invoke_virtual(©, "entrySet", "()Ljava/util/Set;", ()).await?; - let copy_entries: ClassInstanceRef> = jvm.invoke_virtual(©_entries, "toArray", "()[Ljava/lang/Object;", ()).await?; + let copy_entries: ClassInstanceRef = jvm + .invoke_virtual(©, ©.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let copy_entries: ClassInstanceRef> = jvm + .invoke_virtual( + ©_entries, + ©_entries.class_definition().name(), + "toArray", + "()[Ljava/lang/Object;", + (), + ) + .await?; let copy_entry: ClassInstanceRef = jvm.load_array(©_entries, 0, 1).await?.pop().unwrap(); - let copied_key: ClassInstanceRef = jvm.invoke_virtual(©_entry, "getKey", "()Ljava/lang/Object;", ()).await?; + let copied_key: ClassInstanceRef = jvm + .invoke_virtual(©_entry, ©_entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(copied_key.identity(), query_key.identity()); let hashtable = jvm.new_class("java/util/Hashtable", "()V", ()).await?; @@ -983,6 +1246,7 @@ async fn col_10_11_put_all_preserves_equals_direction_and_hashtable_prevalidates let _: ClassInstanceRef = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (original_key.clone(), original_value.clone()), @@ -994,6 +1258,7 @@ async fn col_10_11_put_all_preserves_equals_direction_and_hashtable_prevalidates let _: ClassInstanceRef = jvm .invoke_virtual( &null_key_source, + &null_key_source.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_key, JavaLangString::from_rust_string(&jvm, "invalid-null-key").await?), @@ -1003,6 +1268,7 @@ async fn col_10_11_put_all_preserves_equals_direction_and_hashtable_prevalidates let _: ClassInstanceRef = jvm .invoke_virtual( &null_key_source, + &null_key_source.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", ( @@ -1011,15 +1277,33 @@ async fn col_10_11_put_all_preserves_equals_direction_and_hashtable_prevalidates ), ) .await?; - let result: Result<()> = jvm.invoke_virtual(&hashtable, "putAll", "(Ljava/util/Map;)V", (null_key_source,)).await; + let result: Result<()> = jvm + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (null_key_source,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Hashtable.putAll must reject a null key"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&hashtable, "size", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); assert!( - !jvm.invoke_virtual::<_, bool>(&hashtable, "containsKey", "(Ljava/lang/Object;)Z", (valid_after_null_key,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &hashtable, + &hashtable.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (valid_after_null_key,) + ) + .await? ); let null_value_source = jvm.new_class("java/util/HashMap", "()V", ()).await?; @@ -1028,6 +1312,7 @@ async fn col_10_11_put_all_preserves_equals_direction_and_hashtable_prevalidates let _: ClassInstanceRef = jvm .invoke_virtual( &null_value_source, + &null_value_source.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (invalid_value_key, null_value), @@ -1037,6 +1322,7 @@ async fn col_10_11_put_all_preserves_equals_direction_and_hashtable_prevalidates let _: ClassInstanceRef = jvm .invoke_virtual( &null_value_source, + &null_value_source.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", ( @@ -1045,37 +1331,87 @@ async fn col_10_11_put_all_preserves_equals_direction_and_hashtable_prevalidates ), ) .await?; - let result: Result<()> = jvm.invoke_virtual(&hashtable, "putAll", "(Ljava/util/Map;)V", (null_value_source,)).await; + let result: Result<()> = jvm + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (null_value_source,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Hashtable.putAll must reject a null value"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&hashtable, "size", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); assert!( - !jvm.invoke_virtual::<_, bool>(&hashtable, "containsKey", "(Ljava/lang/Object;)Z", (valid_after_null_value,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &hashtable, + &hashtable.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (valid_after_null_value,) + ) + .await? ); let preserved: ClassInstanceRef = jvm - .invoke_virtual(&hashtable, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (original_key,)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (original_key,), + ) .await?; assert_eq!(preserved.identity(), original_value.identity()); let null_map: ClassInstanceRef = None.into(); for map in [&target, &hashtable] { - let result: Result<()> = jvm.invoke_virtual(map, "putAll", "(Ljava/util/Map;)V", (null_map.clone(),)).await; + let result: Result<()> = jvm + .invoke_virtual(map, &map.class_definition().name(), "putAll", "(Ljava/util/Map;)V", (null_map.clone(),)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("putAll(null) must throw NullPointerException"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); } - let target_size: i32 = jvm.invoke_virtual(&target, "size", "()I", ()).await?; - let _: () = jvm.invoke_virtual(&target, "putAll", "(Ljava/util/Map;)V", (target.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&target, "size", "()I", ()).await?, target_size); - let hashtable_size: i32 = jvm.invoke_virtual(&hashtable, "size", "()I", ()).await?; + let target_size: i32 = jvm.invoke_virtual(&target, &target.class_definition().name(), "size", "()I", ()).await?; + let _: () = jvm + .invoke_virtual( + &target, + &target.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (target.clone(),), + ) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&target, &target.class_definition().name(), "size", "()I", ()) + .await?, + target_size + ); + let hashtable_size: i32 = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?; let _: () = jvm - .invoke_virtual(&hashtable, "putAll", "(Ljava/util/Map;)V", (hashtable.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (hashtable.clone(),), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&hashtable, "size", "()I", ()).await?, hashtable_size); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?, + hashtable_size + ); Ok(()) } @@ -1087,12 +1423,20 @@ async fn col_12_typed_to_array_preserves_multidimensional_components_and_jdk_ase let string_row_1: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/String;", 1).await?.into(); let string_row_2: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/String;", 2).await?.into(); for row in [string_row_1.clone(), string_row_2.clone()] { - let _: bool = jvm.invoke_virtual(&strings, "add", "(Ljava/lang/Object;)Z", (row,)).await?; + let _: bool = jvm + .invoke_virtual(&strings, &strings.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (row,)) + .await?; } let small: ClassInstanceRef> = jvm.instantiate_array("[Ljava/lang/String;", 0).await?.into(); let grown: ClassInstanceRef> = jvm - .invoke_virtual(&strings, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (small,)) + .invoke_virtual( + &strings, + &strings.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (small,), + ) .await?; assert_eq!(grown.class_definition().name(), "[[Ljava/lang/String;"); let grown_rows: Vec> = jvm.load_array(&grown, 0, 2).await?; @@ -1101,7 +1445,13 @@ async fn col_12_typed_to_array_preserves_multidimensional_components_and_jdk_ase let object_matrix: ClassInstanceRef> = jvm.instantiate_array("[Ljava/lang/Object;", 0).await?.into(); let covariant: ClassInstanceRef> = jvm - .invoke_virtual(&strings, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (object_matrix,)) + .invoke_virtual( + &strings, + &strings.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (object_matrix,), + ) .await?; assert_eq!(covariant.class_definition().name(), "[[Ljava/lang/Object;"); @@ -1109,7 +1459,9 @@ async fn col_12_typed_to_array_preserves_multidimensional_components_and_jdk_ase let int_row_1: ClassInstanceRef> = jvm.instantiate_array("I", 1).await?.into(); let int_row_2: ClassInstanceRef> = jvm.instantiate_array("I", 2).await?.into(); for row in [int_row_1.clone(), int_row_2.clone()] { - let _: bool = jvm.invoke_virtual(&ints, "add", "(Ljava/lang/Object;)Z", (row,)).await?; + let _: bool = jvm + .invoke_virtual(&ints, &ints.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (row,)) + .await?; } let sentinel_int_row: ClassInstanceRef> = jvm.instantiate_array("I", 3).await?.into(); let mut int_matrix: ClassInstanceRef> = jvm.instantiate_array("[I", 3).await?.into(); @@ -1121,7 +1473,13 @@ async fn col_12_typed_to_array_preserves_multidimensional_components_and_jdk_ase .await?; let int_matrix_identity = int_matrix.identity(); let reused: ClassInstanceRef> = jvm - .invoke_virtual(&ints, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (int_matrix,)) + .invoke_virtual( + &ints, + &ints.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (int_matrix,), + ) .await?; assert_eq!(reused.identity(), int_matrix_identity); assert_eq!(reused.class_definition().name(), "[[I"); @@ -1133,9 +1491,23 @@ async fn col_12_typed_to_array_preserves_multidimensional_components_and_jdk_ase let incompatible = jvm.new_class("java/util/ArrayList", "()V", ()).await?; let object_row: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/Object;", 1).await?.into(); let _: bool = jvm - .invoke_virtual(&incompatible, "add", "(Ljava/lang/Object;)Z", (string_row_1.clone(),)) + .invoke_virtual( + &incompatible, + &incompatible.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (string_row_1.clone(),), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &incompatible, + &incompatible.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (object_row,), + ) .await?; - let _: bool = jvm.invoke_virtual(&incompatible, "add", "(Ljava/lang/Object;)Z", (object_row,)).await?; let sentinel_string_row: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/String;", 4).await?.into(); let mut destination: ClassInstanceRef> = jvm.instantiate_array("[Ljava/lang/String;", 3).await?.into(); jvm.store_array( @@ -1147,6 +1519,7 @@ async fn col_12_typed_to_array_preserves_multidimensional_components_and_jdk_ase let result: Result>> = jvm .invoke_virtual( &incompatible, + &incompatible.class_definition().name(), "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (destination.clone(),), @@ -1176,11 +1549,19 @@ async fn col_01_bulk_unsupported_mutations_respect_empty_and_pre_mutation_state( let empty = jvm.new_class("SnapshotCollection", "([Ljava/lang/Object;)V", (empty_elements,)).await?; for (name, descriptor) in [("addAll", "(Ljava/util/Collection;)Z"), ("removeAll", "(Ljava/util/Collection;)Z")] { - let changed: bool = jvm.invoke_virtual(&immutable, name, descriptor, (empty.clone(),)).await?; + let changed: bool = jvm + .invoke_virtual(&immutable, &immutable.class_definition().name(), name, descriptor, (empty.clone(),)) + .await?; assert!(!changed); } let retained: bool = jvm - .invoke_virtual(&immutable, "retainAll", "(Ljava/util/Collection;)Z", (immutable.clone(),)) + .invoke_virtual( + &immutable, + &immutable.class_definition().name(), + "retainAll", + "(Ljava/util/Collection;)Z", + (immutable.clone(),), + ) .await?; assert!(!retained); @@ -1189,19 +1570,43 @@ async fn col_01_bulk_unsupported_mutations_respect_empty_and_pre_mutation_state( ("removeAll", immutable.clone()), ("retainAll", empty.clone()), ] { - let result: Result = jvm.invoke_virtual(&immutable, name, "(Ljava/util/Collection;)Z", (argument,)).await; + let result: Result = jvm + .invoke_virtual( + &immutable, + &immutable.class_definition().name(), + name, + "(Ljava/util/Collection;)Z", + (argument,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{name} must reject an unsupported mutation"); }; assert!(jvm.is_instance(&*exception, "java/lang/UnsupportedOperationException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&immutable, "size", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&immutable, &immutable.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); assert!( - jvm.invoke_virtual::<_, bool>(&immutable, "contains", "(Ljava/lang/Object;)Z", (first.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &immutable, + &immutable.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (first.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&immutable, "contains", "(Ljava/lang/Object;)Z", (second.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &immutable, + &immutable.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (second.clone(),) + ) + .await? ); } @@ -1212,45 +1617,98 @@ async fn col_01_bulk_unsupported_mutations_respect_empty_and_pre_mutation_state( let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (map_key_1.clone(), map_value.clone()), ) .await?; - let keys: ClassInstanceRef = jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await?; - let snapshot_iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; - let empty_add: bool = jvm.invoke_virtual(&keys, "addAll", "(Ljava/util/Collection;)Z", (empty.clone(),)).await?; + let keys: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let snapshot_iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let empty_add: bool = jvm + .invoke_virtual( + &keys, + &keys.class_definition().name(), + "addAll", + "(Ljava/util/Collection;)Z", + (empty.clone(),), + ) + .await?; assert!(!empty_add); let result: Result = jvm - .invoke_virtual(&keys, "addAll", "(Ljava/util/Collection;)Z", (immutable.clone(),)) + .invoke_virtual( + &keys, + &keys.class_definition().name(), + "addAll", + "(Ljava/util/Collection;)Z", + (immutable.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("keySet.addAll(nonEmpty) must throw UnsupportedOperationException"); }; assert!(jvm.is_instance(&*exception, "java/lang/UnsupportedOperationException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&map, "size", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&map, &map.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (map_key_2.clone(), map_value), ) .await?; let target = jvm.new_class("java/util/ArrayList", "()V", ()).await?; - let _: bool = jvm.invoke_virtual(&target, "addAll", "(Ljava/util/Collection;)Z", (keys,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&target, "size", "()I", ()).await?, 2); - let snapshot_first: ClassInstanceRef = jvm.invoke_virtual(&snapshot_iterator, "next", "()Ljava/lang/Object;", ()).await?; + let _: bool = jvm + .invoke_virtual(&target, &target.class_definition().name(), "addAll", "(Ljava/util/Collection;)Z", (keys,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&target, &target.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); + let snapshot_first: ClassInstanceRef = jvm + .invoke_virtual( + &snapshot_iterator, + &snapshot_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; assert_eq!(snapshot_first.identity(), map_key_1.identity()); - assert!(!jvm.invoke_virtual::<_, bool>(&snapshot_iterator, "hasNext", "()Z", ()).await?); assert!( - jvm.invoke_virtual::<_, bool>(&target, "contains", "(Ljava/lang/Object;)Z", (map_key_1,)) + !jvm.invoke_virtual::<_, bool>(&snapshot_iterator, &snapshot_iterator.class_definition().name(), "hasNext", "()Z", ()) .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&target, "contains", "(Ljava/lang/Object;)Z", (map_key_2,)) - .await? + jvm.invoke_virtual::<_, bool>( + &target, + &target.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (map_key_1,) + ) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>( + &target, + &target.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (map_key_2,) + ) + .await? ); Ok(()) @@ -1268,17 +1726,32 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store let _: ClassInstanceRef = jvm .invoke_virtual( &asymmetric_key_map, + &asymmetric_key_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (stored_key.clone(), stored_key_value.clone()), ) .await?; assert!( - jvm.invoke_virtual::<_, bool>(&asymmetric_key_map, "containsKey", "(Ljava/lang/Object;)Z", (query_key.clone(),),) - .await?, + jvm.invoke_virtual::<_, bool>( + &asymmetric_key_map, + &asymmetric_key_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (query_key.clone(),), + ) + .await?, "the query key must find the stored key before EntrySet applies stored-key equality" ); - let asymmetric_entries: ClassInstanceRef = jvm.invoke_virtual(&asymmetric_key_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let asymmetric_entries: ClassInstanceRef = jvm + .invoke_virtual( + &asymmetric_key_map, + &asymmetric_key_map.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; let asymmetric_contains: ClassInstanceRef = jvm .new_class( "StatefulMapEntry", @@ -1288,12 +1761,22 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&asymmetric_entries, "contains", "(Ljava/lang/Object;)Z", (asymmetric_contains.clone(),),) - .await? + !jvm.invoke_virtual::<_, bool>( + &asymmetric_entries, + &asymmetric_entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (asymmetric_contains.clone(),), + ) + .await? ); assert_eq!(jvm.get_field::(&asymmetric_contains, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&asymmetric_contains, "valueCalls", "I").await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&asymmetric_key_map, "size", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&asymmetric_key_map, &asymmetric_key_map.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); let asymmetric_remove: ClassInstanceRef = jvm .new_class( @@ -1304,31 +1787,85 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&asymmetric_entries, "remove", "(Ljava/lang/Object;)Z", (asymmetric_remove.clone(),),) - .await? + !jvm.invoke_virtual::<_, bool>( + &asymmetric_entries, + &asymmetric_entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (asymmetric_remove.clone(),), + ) + .await? ); assert_eq!(jvm.get_field::(&asymmetric_remove, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&asymmetric_remove, "valueCalls", "I").await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&asymmetric_key_map, "size", "()I", ()).await?, 1); - let preserved_iterator: ClassInstanceRef = jvm.invoke_virtual(&asymmetric_entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let preserved_entry: ClassInstanceRef = jvm.invoke_virtual(&preserved_iterator, "next", "()Ljava/lang/Object;", ()).await?; - let preserved_key: ClassInstanceRef = jvm.invoke_virtual(&preserved_entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let preserved_value: ClassInstanceRef = jvm.invoke_virtual(&preserved_entry, "getValue", "()Ljava/lang/Object;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&asymmetric_key_map, &asymmetric_key_map.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); + let preserved_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &asymmetric_entries, + &asymmetric_entries.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let preserved_entry: ClassInstanceRef = jvm + .invoke_virtual( + &preserved_iterator, + &preserved_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; + let preserved_key: ClassInstanceRef = jvm + .invoke_virtual( + &preserved_entry, + &preserved_entry.class_definition().name(), + "getKey", + "()Ljava/lang/Object;", + (), + ) + .await?; + let preserved_value: ClassInstanceRef = jvm + .invoke_virtual( + &preserved_entry, + &preserved_entry.class_definition().name(), + "getValue", + "()Ljava/lang/Object;", + (), + ) + .await?; assert_eq!(preserved_key.identity(), stored_key.identity()); assert_eq!(preserved_value.identity(), stored_key_value.identity()); - assert!(!jvm.invoke_virtual::<_, bool>(&preserved_iterator, "hasNext", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&preserved_iterator, &preserved_iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + ); let null_key_map = jvm.new_class("java/util/HashMap", "()V", ()).await?; let null_key_value = JavaLangString::from_rust_string(&jvm, "null-key-value").await?; let _: ClassInstanceRef = jvm .invoke_virtual( &null_key_map, + &null_key_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null.clone(), null_key_value.clone()), ) .await?; - let null_key_entries: ClassInstanceRef = jvm.invoke_virtual(&null_key_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let null_key_entries: ClassInstanceRef = jvm + .invoke_virtual( + &null_key_map, + &null_key_map.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; let null_key_contains: ClassInstanceRef = jvm .new_class( "StatefulMapEntry", @@ -1338,8 +1875,14 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&null_key_entries, "contains", "(Ljava/lang/Object;)Z", (null_key_contains.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &null_key_entries, + &null_key_entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null_key_contains.clone(),), + ) + .await? ); assert_eq!(jvm.get_field::(&null_key_contains, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&null_key_contains, "valueCalls", "I").await?, 1); @@ -1352,12 +1895,22 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&null_key_entries, "remove", "(Ljava/lang/Object;)Z", (null_key_remove.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &null_key_entries, + &null_key_entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (null_key_remove.clone(),), + ) + .await? ); assert_eq!(jvm.get_field::(&null_key_remove, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&null_key_remove, "valueCalls", "I").await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&null_key_map, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&null_key_map, &null_key_map.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); for map_class in ["java/util/HashMap", "java/util/Hashtable"] { let map: ClassInstanceRef = jvm.new_class(map_class, "()V", ()).await?.into(); @@ -1367,12 +1920,15 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), stored_value.clone()), ) .await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; let contains_candidate: ClassInstanceRef = jvm .new_class( "StatefulMapEntry", @@ -1382,8 +1938,14 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&entries, "contains", "(Ljava/lang/Object;)Z", (contains_candidate.clone(),)) - .await?, + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (contains_candidate.clone(),) + ) + .await?, "{map_class} EntrySet.contains must use storedValue.equals(candidateValue)" ); assert_eq!(jvm.get_field::(&contains_candidate, "keyCalls", "I").await?, 1); @@ -1400,15 +1962,25 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&entries, "remove", "(Ljava/lang/Object;)Z", (remove_candidate.clone(),)) - .await?, + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (remove_candidate.clone(),) + ) + .await?, "{map_class} EntrySet.remove must use storedValue.equals(candidateValue)" ); assert_eq!(jvm.get_field::(&remove_candidate, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&remove_candidate, "valueCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&stored_value, "equalsCalls", "I").await?, 2); assert_eq!(jvm.get_field::(&candidate_value, "equalsCalls", "I").await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&map, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&map, &map.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); let opposite_map: ClassInstanceRef = jvm.new_class(map_class, "()V", ()).await?.into(); let opposite_key = JavaLangString::from_rust_string(&jvm, "opposite-key").await?; @@ -1417,12 +1989,21 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store let _: ClassInstanceRef = jvm .invoke_virtual( &opposite_map, + &opposite_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (opposite_key.clone(), rejecting_stored.clone()), ) .await?; - let opposite_entries: ClassInstanceRef = jvm.invoke_virtual(&opposite_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let opposite_entries: ClassInstanceRef = jvm + .invoke_virtual( + &opposite_map, + &opposite_map.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; let opposite_candidate: ClassInstanceRef = jvm .new_class( "StatefulMapEntry", @@ -1432,8 +2013,14 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&opposite_entries, "contains", "(Ljava/lang/Object;)Z", (opposite_candidate,),) - .await? + !jvm.invoke_virtual::<_, bool>( + &opposite_entries, + &opposite_entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (opposite_candidate,), + ) + .await? ); assert_eq!(jvm.get_field::(&rejecting_stored, "equalsCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&accepting_candidate, "equalsCalls", "I").await?, 0); @@ -1447,13 +2034,22 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store let _: ClassInstanceRef = jvm .invoke_virtual( &stateful_map, + &stateful_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value), ) .await?; } - let stateful_entries: ClassInstanceRef = jvm.invoke_virtual(&stateful_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let stateful_entries: ClassInstanceRef = jvm + .invoke_virtual( + &stateful_map, + &stateful_map.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; let alternating: ClassInstanceRef = jvm .new_class( "StatefulMapEntry", @@ -1468,21 +2064,45 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&stateful_entries, "remove", "(Ljava/lang/Object;)Z", (alternating.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &stateful_entries, + &stateful_entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (alternating.clone(),) + ) + .await? ); assert_eq!(jvm.get_field::(&alternating, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&alternating, "valueCalls", "I").await?, 1); assert!( - !jvm.invoke_virtual::<_, bool>(&stateful_map, "containsKey", "(Ljava/lang/Object;)Z", (first_key,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &stateful_map, + &stateful_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (first_key,) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&stateful_map, "containsKey", "(Ljava/lang/Object;)Z", (later_key.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &stateful_map, + &stateful_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (later_key.clone(),) + ) + .await? ); let preserved: ClassInstanceRef = jvm - .invoke_virtual(&stateful_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (later_key.clone(),)) + .invoke_virtual( + &stateful_map, + &stateful_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (later_key.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &preserved).await?, "later-value"); @@ -1496,8 +2116,14 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&stateful_entries, "contains", "(Ljava/lang/Object;)Z", (missing_contains.clone(),),) - .await? + !jvm.invoke_virtual::<_, bool>( + &stateful_entries, + &stateful_entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (missing_contains.clone(),), + ) + .await? ); assert_eq!(jvm.get_field::(&missing_contains, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&missing_contains, "valueCalls", "I").await?, 0); @@ -1511,8 +2137,14 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&stateful_entries, "remove", "(Ljava/lang/Object;)Z", (missing_remove.clone(),),) - .await? + !jvm.invoke_virtual::<_, bool>( + &stateful_entries, + &stateful_entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (missing_remove.clone(),), + ) + .await? ); assert_eq!(jvm.get_field::(&missing_remove, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&missing_remove, "valueCalls", "I").await?, 0); @@ -1526,7 +2158,13 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); let result: Result = jvm - .invoke_virtual(&stateful_entries, "contains", "(Ljava/lang/Object;)Z", (throwing_key.clone(),)) + .invoke_virtual( + &stateful_entries, + &stateful_entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (throwing_key.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{map_class} EntrySet.contains must propagate getKey exceptions"); @@ -1544,7 +2182,13 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); let result: Result = jvm - .invoke_virtual(&stateful_entries, "remove", "(Ljava/lang/Object;)Z", (throwing_remove_key.clone(),)) + .invoke_virtual( + &stateful_entries, + &stateful_entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (throwing_remove_key.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{map_class} EntrySet.remove must propagate getKey exceptions"); @@ -1562,7 +2206,13 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); let result: Result = jvm - .invoke_virtual(&stateful_entries, "contains", "(Ljava/lang/Object;)Z", (throwing_contains_value.clone(),)) + .invoke_virtual( + &stateful_entries, + &stateful_entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (throwing_contains_value.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{map_class} EntrySet.contains must propagate getValue exceptions for a found key"); @@ -1580,7 +2230,13 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); let result: Result = jvm - .invoke_virtual(&stateful_entries, "remove", "(Ljava/lang/Object;)Z", (throwing_value.clone(),)) + .invoke_virtual( + &stateful_entries, + &stateful_entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (throwing_value.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{map_class} EntrySet.remove must propagate getValue exceptions for a found key"); @@ -1589,19 +2245,37 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store assert_eq!(jvm.get_field::(&throwing_value, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&throwing_value, "valueCalls", "I").await?, 1); assert!( - jvm.invoke_virtual::<_, bool>(&stateful_map, "containsKey", "(Ljava/lang/Object;)Z", (later_key.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &stateful_map, + &stateful_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (later_key.clone(),) + ) + .await? ); let non_entry: ClassInstanceRef = jvm.new_class("java/lang/Object", "()V", ()).await?.into(); for candidate in [null.clone(), non_entry] { assert!( - !jvm.invoke_virtual::<_, bool>(&stateful_entries, "contains", "(Ljava/lang/Object;)Z", (candidate.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &stateful_entries, + &stateful_entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (candidate.clone(),) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&stateful_entries, "remove", "(Ljava/lang/Object;)Z", (candidate,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &stateful_entries, + &stateful_entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (candidate,) + ) + .await? ); } @@ -1615,12 +2289,24 @@ async fn coll_08_entry_set_contains_and_remove_snapshot_candidates_and_use_store .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&stateful_entries, "contains", "(Ljava/lang/Object;)Z", (null_key.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &stateful_entries, + &stateful_entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null_key.clone(),) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&stateful_entries, "remove", "(Ljava/lang/Object;)Z", (null_key.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &stateful_entries, + &stateful_entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (null_key.clone(),) + ) + .await? ); assert_eq!(jvm.get_field::(&null_key, "keyCalls", "I").await?, 2); assert_eq!(jvm.get_field::(&null_key, "valueCalls", "I").await?, 0); @@ -1642,7 +2328,13 @@ async fn hashtable_equals_and_hash_code_match_map_value_contracts() -> Result<() let key: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, key).await?.into(); let value: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (value,)).await?.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } } @@ -1655,12 +2347,18 @@ async fn hashtable_equals_and_hash_code_match_map_value_contracts() -> Result<() ) .await?; let maps = [&hashtable, &hash_map, &tree_map, &unmodifiable]; - let expected_hash: i32 = jvm.invoke_virtual(&hashtable, "hashCode", "()I", ()).await?; + let expected_hash: i32 = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "hashCode", "()I", ()) + .await?; for left in maps { - assert_eq!(jvm.invoke_virtual::<_, i32>(left, "hashCode", "()I", ()).await?, expected_hash); + assert_eq!( + jvm.invoke_virtual::<_, i32>(left, &left.class_definition().name(), "hashCode", "()I", ()) + .await?, + expected_hash + ); for right in maps { assert!( - jvm.invoke_virtual::<_, bool>(left, "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) + jvm.invoke_virtual::<_, bool>(left, &left.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (right.clone(),)) .await?, "{} must equal {}", left.class_definition().name(), @@ -1670,30 +2368,60 @@ async fn hashtable_equals_and_hash_code_match_map_value_contracts() -> Result<() } assert!( - jvm.invoke_virtual::<_, bool>(&hashtable, "equals", "(Ljava/lang/Object;)Z", (hashtable.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &hashtable, + &hashtable.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (hashtable.clone(),) + ) + .await? ); let null: ClassInstanceRef = None.into(); assert!( - !jvm.invoke_virtual::<_, bool>(&hashtable, "equals", "(Ljava/lang/Object;)Z", (null,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &hashtable, + &hashtable.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null,) + ) + .await? ); let non_map: ClassInstanceRef = jvm.new_class("java/lang/Object", "()V", ()).await?.into(); assert!( - !jvm.invoke_virtual::<_, bool>(&hashtable, "equals", "(Ljava/lang/Object;)Z", (non_map,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &hashtable, + &hashtable.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (non_map,) + ) + .await? ); let different_size: ClassInstanceRef = jvm.new_class("java/util/HashMap", "()V", ()).await?.into(); assert!( - !jvm.invoke_virtual::<_, bool>(&hashtable, "equals", "(Ljava/lang/Object;)Z", (different_size,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &hashtable, + &hashtable.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (different_size,) + ) + .await? ); for mode in [0, 1] { let throwing: ClassInstanceRef = jvm.new_class("ThrowingMap", "(II)V", (2, mode)).await?.into(); assert!( - !jvm.invoke_virtual::<_, bool>(&hashtable, "equals", "(Ljava/lang/Object;)Z", (throwing,)) - .await?, + !jvm.invoke_virtual::<_, bool>( + &hashtable, + &hashtable.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (throwing,) + ) + .await?, "Hashtable.equals must convert mode {mode} NPE/CCE to false" ); } @@ -1707,21 +2435,26 @@ async fn hashtable_hash_code_guards_self_key_and_value_recursion() -> Result<()> let self_value: ClassInstanceRef = jvm.new_class("java/util/Hashtable", "()V", ()).await?.into(); let value_key: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "self-value").await?.into(); - let expected_value_hash: i32 = jvm.invoke_virtual(&value_key, "hashCode", "()I", ()).await?; + let expected_value_hash: i32 = jvm + .invoke_virtual(&value_key, &value_key.class_definition().name(), "hashCode", "()I", ()) + .await?; let _: ClassInstanceRef = jvm .invoke_virtual( &self_value, + &self_value.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (value_key, self_value.clone()), ) .await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&self_value, "hashCode", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&self_value, &self_value.class_definition().name(), "hashCode", "()I", ()) + .await?, expected_value_hash ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&self_value, "hashCode", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>(&self_value, &self_value.class_definition().name(), "hashCode", "()I", ()) + .await?, expected_value_hash ); @@ -1730,23 +2463,33 @@ async fn hashtable_hash_code_guards_self_key_and_value_recursion() -> Result<()> let _: ClassInstanceRef = jvm .invoke_virtual( &self_key, + &self_key.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (self_key.clone(), key_value), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&self_key, "hashCode", "()I", ()).await?, 37); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&self_key, &self_key.class_definition().name(), "hashCode", "()I", ()) + .await?, + 37 + ); let self_both: ClassInstanceRef = jvm.new_class("java/util/Hashtable", "()V", ()).await?.into(); let _: ClassInstanceRef = jvm .invoke_virtual( &self_both, + &self_both.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (self_both.clone(), self_both.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&self_both, "hashCode", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&self_both, &self_both.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0 + ); Ok(()) } @@ -1760,14 +2503,21 @@ async fn hashtable_entry_equals_and_hash_code_follow_map_entry_contract() -> Res let _: ClassInstanceRef = jvm .invoke_virtual( &table, + &table.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value.clone()), ) .await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&table, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&table, &table.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let different_key: ClassInstanceRef = JavaLangString::from_rust_string(&jvm, "different").await?.into(); let short_circuit: ClassInstanceRef = jvm @@ -1779,8 +2529,14 @@ async fn hashtable_entry_equals_and_hash_code_follow_map_entry_contract() -> Res .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&entry, "equals", "(Ljava/lang/Object;)Z", (short_circuit.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &entry, + &entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (short_circuit.clone(),) + ) + .await? ); assert_eq!(jvm.get_field::(&short_circuit, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&short_circuit, "valueCalls", "I").await?, 0); @@ -1794,7 +2550,13 @@ async fn hashtable_entry_equals_and_hash_code_follow_map_entry_contract() -> Res .await? .into(); let result: Result = jvm - .invoke_virtual(&entry, "equals", "(Ljava/lang/Object;)Z", (throwing_key.clone(),)) + .invoke_virtual( + &entry, + &entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (throwing_key.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Hashtable.Entry.equals must propagate getKey exceptions"); @@ -1812,7 +2574,13 @@ async fn hashtable_entry_equals_and_hash_code_follow_map_entry_contract() -> Res .await? .into(); let result: Result = jvm - .invoke_virtual(&entry, "equals", "(Ljava/lang/Object;)Z", (throwing_value.clone(),)) + .invoke_virtual( + &entry, + &entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (throwing_value.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Hashtable.Entry.equals must propagate getValue exceptions after matching keys"); @@ -1829,14 +2597,39 @@ async fn hashtable_entry_equals_and_hash_code_follow_map_entry_contract() -> Res let _: ClassInstanceRef = jvm .invoke_virtual( &directional_table, + &directional_table.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (stored_key.clone(), stored_value.clone()), ) .await?; - let directional_entries: ClassInstanceRef = jvm.invoke_virtual(&directional_table, "entrySet", "()Ljava/util/Set;", ()).await?; - let directional_iterator: ClassInstanceRef = jvm.invoke_virtual(&directional_entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let directional_entry: ClassInstanceRef = jvm.invoke_virtual(&directional_iterator, "next", "()Ljava/lang/Object;", ()).await?; + let directional_entries: ClassInstanceRef = jvm + .invoke_virtual( + &directional_table, + &directional_table.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; + let directional_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &directional_entries, + &directional_entries.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let directional_entry: ClassInstanceRef = jvm + .invoke_virtual( + &directional_iterator, + &directional_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; let directional_candidate: ClassInstanceRef = jvm .new_class( "StatefulMapEntry", @@ -1846,8 +2639,14 @@ async fn hashtable_entry_equals_and_hash_code_follow_map_entry_contract() -> Res .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&directional_entry, "equals", "(Ljava/lang/Object;)Z", (directional_candidate.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &directional_entry, + &directional_entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (directional_candidate.clone(),), + ) + .await? ); assert_eq!(jvm.get_field::(&directional_candidate, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&directional_candidate, "valueCalls", "I").await?, 1); @@ -1867,7 +2666,11 @@ async fn hashtable_entry_equals_and_hash_code_follow_map_entry_contract() -> Res ) .await? .into(); - assert_eq!(jvm.invoke_virtual::<_, i32>(&integer_entry, "hashCode", "()I", ()).await?, 7 ^ 11); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&integer_entry, &integer_entry.class_definition().name(), "hashCode", "()I", ()) + .await?, + 7 ^ 11 + ); let null_entry: ClassInstanceRef = jvm .new_class( @@ -1886,20 +2689,42 @@ async fn hashtable_entry_equals_and_hash_code_follow_map_entry_contract() -> Res .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&null_entry, "equals", "(Ljava/lang/Object;)Z", (null_candidate.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &null_entry, + &null_entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_candidate.clone(),) + ) + .await? ); assert_eq!(jvm.get_field::(&null_candidate, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&null_candidate, "valueCalls", "I").await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&null_entry, "hashCode", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&null_entry, &null_entry.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0 + ); assert!( - !jvm.invoke_virtual::<_, bool>(&null_entry, "equals", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &null_entry, + &null_entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); let non_entry: ClassInstanceRef = jvm.new_class("java/lang/Object", "()V", ()).await?.into(); assert!( - !jvm.invoke_virtual::<_, bool>(&null_entry, "equals", "(Ljava/lang/Object;)Z", (non_entry,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &null_entry, + &null_entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (non_entry,) + ) + .await? ); Ok(()) diff --git a/java_runtime/tests/classes/java/util/test_collections.rs b/java_runtime/tests/classes/java/util/test_collections.rs index 9aa59a5e..49580ca4 100644 --- a/java_runtime/tests/classes/java/util/test_collections.rs +++ b/java_runtime/tests/classes/java/util/test_collections.rs @@ -299,7 +299,8 @@ impl CollectionsExceptionalSet { let list = jvm .new_class("java/util/Collections$CopiesList", "(ILjava/lang/Object;)V", (1, element)) .await?; - jvm.invoke_virtual(&list, "iterator", "()Ljava/util/Iterator;", ()).await + jvm.invoke_virtual(&list, &list.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await } async fn contains(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef, target: ClassInstanceRef) -> Result { @@ -314,7 +315,8 @@ impl CollectionsExceptionalSet { } else if target.is_null() { Ok(false) } else { - jvm.invoke_virtual(&element, "equals", "(Ljava/lang/Object;)Z", (target,)).await + jvm.invoke_virtual(&element, &element.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (target,)) + .await } } } @@ -500,17 +502,24 @@ async fn integer_list(jvm: &Jvm, values: &[i32]) -> Result = jvm.new_class("java/util/ArrayList", "()V", ()).await?.into(); for value in values { let element: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (*value,)).await?.into(); - let _: bool = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (element,)).await?; + let _: bool = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (element,)) + .await?; } Ok(list) } async fn integer_values(jvm: &Jvm, list: &ClassInstanceRef) -> Result> { - let size: i32 = jvm.invoke_virtual(list, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(list, &list.class_definition().name(), "size", "()I", ()).await?; let mut values = Vec::with_capacity(size as usize); for index in 0..size { - let element: ClassInstanceRef = jvm.invoke_virtual(list, "get", "(I)Ljava/lang/Object;", (index,)).await?; - values.push(jvm.invoke_virtual(&element, "intValue", "()I", ()).await?); + let element: ClassInstanceRef = jvm + .invoke_virtual(list, &list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (index,)) + .await?; + values.push( + jvm.invoke_virtual(&element, &element.class_definition().name(), "intValue", "()I", ()) + .await?, + ); } Ok(values) } @@ -575,8 +584,16 @@ async fn test_coll_01_exact_descriptors_access_and_singletons() -> Result<()> { assert_eq!(empty_list.identity(), same_empty_list.identity()); assert!(jvm.is_instance(empty_list.as_ref(), "java/util/List")); assert!(jvm.is_instance(empty_set.as_ref(), "java/util/Set")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&empty_list, "size", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&empty_set, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&empty_list, &empty_list.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&empty_set, &empty_set.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); for (name, parent) in [ ("java/util/Collections$EmptyList", "java/util/AbstractList"), @@ -743,7 +760,15 @@ async fn test_coll_03_binary_search_insertion_duplicates_and_comparator() -> Res let reverse_list: ClassInstanceRef = jvm.new_class("java/util/ArrayList", "()V", ()).await?.into(); for key in [3, 2, 1] { let value: ClassInstanceRef = jvm.new_class("CollectionsSortValue", "(IIZ)V", (key, key, false)).await?.into(); - let _: bool = jvm.invoke_virtual(&reverse_list, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual( + &reverse_list, + &reverse_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (value,), + ) + .await?; } let comparator: ClassInstanceRef = jvm.new_class("CollectionsComparator", "(ZZ)V", (true, false)).await?.into(); let key: ClassInstanceRef = jvm.new_class("CollectionsSortValue", "(IIZ)V", (2, 9, false)).await?.into(); @@ -942,13 +967,29 @@ async fn test_coll_06_min_max_natural_comparator_empty_and_null() -> Result<()> (values.clone(),), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&min, "intValue", "()I", ()).await?, -2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&max, "intValue", "()I", ()).await?, 7); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&min, &min.class_definition().name(), "intValue", "()I", ()) + .await?, + -2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&max, &max.class_definition().name(), "intValue", "()I", ()) + .await?, + 7 + ); let comparable_values: ClassInstanceRef = jvm.new_class("java/util/ArrayList", "()V", ()).await?.into(); for key in [1, 3, 2] { let value: ClassInstanceRef = jvm.new_class("CollectionsSortValue", "(IIZ)V", (key, key, false)).await?.into(); - let _: bool = jvm.invoke_virtual(&comparable_values, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual( + &comparable_values, + &comparable_values.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (value,), + ) + .await?; } let reverse: ClassInstanceRef = jvm.new_class("CollectionsComparator", "(ZZ)V", (true, false)).await?.into(); let comparator_min: ClassInstanceRef = jvm @@ -989,8 +1030,12 @@ async fn test_coll_06_min_max_natural_comparator_empty_and_null() -> Result<()> let nulls: ClassInstanceRef = jvm.new_class("java/util/ArrayList", "()V", ()).await?.into(); let null: ClassInstanceRef = None.into(); let value: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (1,)).await?.into(); - let _: bool = jvm.invoke_virtual(&nulls, "add", "(Ljava/lang/Object;)Z", (null,)).await?; - let _: bool = jvm.invoke_virtual(&nulls, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual(&nulls, &nulls.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (null,)) + .await?; + let _: bool = jvm + .invoke_virtual(&nulls, &nulls.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; let result: Result> = jvm .invoke_static("java/util/Collections", "min", "(Ljava/util/Collection;)Ljava/lang/Object;", (nulls,)) .await; @@ -1016,13 +1061,25 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> .await?; assert_eq!(integer_values(&jvm, &copies).await?, vec![11, 11, 11]); assert_eq!( - jvm.invoke_virtual::<_, i32>(&copies, "indexOf", "(Ljava/lang/Object;)I", (element.clone(),)) - .await?, + jvm.invoke_virtual::<_, i32>( + &copies, + &copies.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (element.clone(),) + ) + .await?, 0 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&copies, "lastIndexOf", "(Ljava/lang/Object;)I", (element.clone(),)) - .await?, + jvm.invoke_virtual::<_, i32>( + &copies, + &copies.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/Object;)I", + (element.clone(),) + ) + .await?, 2 ); @@ -1039,13 +1096,21 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/IllegalArgumentException")); - let add_result: Result = jvm.invoke_virtual(&copies, "add", "(Ljava/lang/Object;)Z", (element.clone(),)).await; + let add_result: Result = jvm + .invoke_virtual( + &copies, + &copies.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = add_result else { panic!("nCopies.add must fail"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let clear_result: Result<()> = jvm.invoke_virtual(&copies, "clear", "()V", ()).await; + let clear_result: Result<()> = jvm.invoke_virtual(&copies, &copies.class_definition().name(), "clear", "()V", ()).await; let Err(JavaError::JavaException(exception)) = clear_result else { panic!("non-empty nCopies.clear must fail"); }; @@ -1058,20 +1123,52 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> (0, element.clone()), ) .await?; - let _: () = jvm.invoke_virtual(&zero_copies, "clear", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&zero_copies, &zero_copies.class_definition().name(), "clear", "()V", ()) + .await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&copies, "iterator", "()Ljava/util/Iterator;", ()).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let remove_result: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&copies, &copies.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let remove_result: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = remove_result else { panic!("nCopies iterator.remove must fail"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let list_iterator: ClassInstanceRef = jvm.invoke_virtual(&copies, "listIterator", "()Ljava/util/ListIterator;", ()).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&list_iterator, "next", "()Ljava/lang/Object;", ()).await?; + let list_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &copies, + &copies.class_definition().name(), + "listIterator", + "()Ljava/util/ListIterator;", + (), + ) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &list_iterator, + &list_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; for (name, descriptor) in [("set", "(Ljava/lang/Object;)V"), ("add", "(Ljava/lang/Object;)V")] { - let result: Result<()> = jvm.invoke_virtual(&list_iterator, name, descriptor, (element.clone(),)).await; + let result: Result<()> = jvm + .invoke_virtual( + &list_iterator, + &list_iterator.class_definition().name(), + name, + descriptor, + (element.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("nCopies listIterator.{name} must fail"); }; @@ -1086,28 +1183,58 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> (element.clone(),), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&singleton, "size", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&singleton, &singleton.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); assert!( - jvm.invoke_virtual::<_, bool>(&singleton, "contains", "(Ljava/lang/Object;)Z", (element.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &singleton, + &singleton.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (element.clone(),) + ) + .await? ); - let singleton_iterator: ClassInstanceRef = jvm.invoke_virtual(&singleton, "iterator", "()Ljava/util/Iterator;", ()).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&singleton_iterator, "next", "()Ljava/lang/Object;", ()).await?; - let remove_result: Result<()> = jvm.invoke_virtual(&singleton_iterator, "remove", "()V", ()).await; + let singleton_iterator: ClassInstanceRef = jvm + .invoke_virtual(&singleton, &singleton.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &singleton_iterator, + &singleton_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; + let remove_result: Result<()> = jvm + .invoke_virtual(&singleton_iterator, &singleton_iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = remove_result else { panic!("singleton iterator.remove must fail"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let singleton_clear: Result<()> = jvm.invoke_virtual(&singleton, "clear", "()V", ()).await; + let singleton_clear: Result<()> = jvm + .invoke_virtual(&singleton, &singleton.class_definition().name(), "clear", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = singleton_clear else { panic!("singleton.clear must fail"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); let absent: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (99,)).await?.into(); assert!( - !jvm.invoke_virtual::<_, bool>(&singleton, "remove", "(Ljava/lang/Object;)Z", (absent,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &singleton, + &singleton.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (absent,) + ) + .await? ); let one_copy: ClassInstanceRef = jvm @@ -1124,20 +1251,44 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> } let empty: ClassInstanceRef = jvm.get_static_field("java/util/Collections", "EMPTY_LIST", "Ljava/util/List;").await?; - let _: () = jvm.invoke_virtual(&empty, "clear", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&empty, &empty.class_definition().name(), "clear", "()V", ()).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&empty, "remove", "(Ljava/lang/Object;)Z", (element.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &empty, + &empty.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (element.clone(),) + ) + .await? ); - let add_result: Result = jvm.invoke_virtual(&empty, "add", "(Ljava/lang/Object;)Z", (element.clone(),)).await; + let add_result: Result = jvm + .invoke_virtual( + &empty, + &empty.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = add_result else { panic!("EMPTY_LIST.add must fail"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); let empty_set: ClassInstanceRef = jvm.get_static_field("java/util/Collections", "EMPTY_SET", "Ljava/util/Set;").await?; - let _: () = jvm.invoke_virtual(&empty_set, "clear", "()V", ()).await?; - let add_result: Result = jvm.invoke_virtual(&empty_set, "add", "(Ljava/lang/Object;)Z", (element.clone(),)).await; + let _: () = jvm + .invoke_virtual(&empty_set, &empty_set.class_definition().name(), "clear", "()V", ()) + .await?; + let add_result: Result = jvm + .invoke_virtual( + &empty_set, + &empty_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = add_result else { panic!("EMPTY_SET.add must fail"); }; @@ -1150,7 +1301,9 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> (copies.clone(), "retainAll", "(Ljava/util/Collection;)Z", empty.clone()), (singleton.clone(), "removeAll", "(Ljava/util/Collection;)Z", removal_source), ] { - let result: Result = jvm.invoke_virtual(&target, name, descriptor, (argument,)).await; + let result: Result = jvm + .invoke_virtual(&target, &target.class_definition().name(), name, descriptor, (argument,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{name} requiring mutation must fail"); }; @@ -1158,8 +1311,14 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> } assert!( - !jvm.invoke_virtual::<_, bool>(&copies, "addAll", "(Ljava/util/Collection;)Z", (zero_copies.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &copies, + &copies.class_definition().name(), + "addAll", + "(Ljava/util/Collection;)Z", + (zero_copies.clone(),) + ) + .await? ); let text = JavaLangString::from_rust_string(&jvm, "text").await?; @@ -1173,7 +1332,13 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> .await?; let destination: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/String;", 3).await?.into(); let typed: ClassInstanceRef> = jvm - .invoke_virtual(&text_copies, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (destination,)) + .invoke_virtual( + &text_copies, + &text_copies.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (destination,), + ) .await?; let typed_values = jvm.load_array::>(&typed, 0, 3).await?; assert_eq!(typed_values[0].identity(), text.identity()); @@ -1190,7 +1355,7 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> ) .await?; assert!( - jvm.invoke_virtual::<_, ClassInstanceRef>(&null_copies, "get", "(I)Ljava/lang/Object;", (1,)) + jvm.invoke_virtual::<_, ClassInstanceRef>(&null_copies, &null_copies.class_definition().name(), "get", "(I)Ljava/lang/Object;", (1,)) .await? .is_null() ); @@ -1203,8 +1368,14 @@ async fn test_coll_07_ncopies_singleton_and_empty_are_immutable() -> Result<()> ) .await?; assert!( - jvm.invoke_virtual::<_, bool>(&null_singleton, "contains", "(Ljava/lang/Object;)Z", (null,)) - .await? + jvm.invoke_virtual::<_, bool>( + &null_singleton, + &null_singleton.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null,) + ) + .await? ); Ok(()) @@ -1221,36 +1392,96 @@ async fn test_coll_07_immutable_equals_and_hash_code_match_standard_collections( for collection in [empty_list.clone(), empty_set.clone()] { assert!( - !jvm.invoke_virtual::<_, bool>(&collection, "equals", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &collection, + &collection.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? + ); + let first_hash: i32 = jvm + .invoke_virtual(&collection, &collection.class_definition().name(), "hashCode", "()I", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&collection, &collection.class_definition().name(), "hashCode", "()I", ()) + .await?, + first_hash ); - let first_hash: i32 = jvm.invoke_virtual(&collection, "hashCode", "()I", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&collection, "hashCode", "()I", ()).await?, first_hash); } assert!( - jvm.invoke_virtual::<_, bool>(&empty_list, "equals", "(Ljava/lang/Object;)Z", (standard_empty_list.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &empty_list, + &empty_list.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (standard_empty_list.clone(),), + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&standard_empty_list, "equals", "(Ljava/lang/Object;)Z", (empty_list.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &standard_empty_list, + &standard_empty_list.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (empty_list.clone(),), + ) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&empty_list, &empty_list.class_definition().name(), "hashCode", "()I", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &standard_empty_list, + &standard_empty_list.class_definition().name(), + "hashCode", + "()I", + () + ) + .await?, + 1 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&empty_list, "hashCode", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&standard_empty_list, "hashCode", "()I", ()).await?, 1); assert!( - jvm.invoke_virtual::<_, bool>(&empty_set, "equals", "(Ljava/lang/Object;)Z", (standard_empty_set.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &empty_set, + &empty_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (standard_empty_set.clone(),), + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&standard_empty_set, "equals", "(Ljava/lang/Object;)Z", (empty_set.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &standard_empty_set, + &standard_empty_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (empty_set.clone(),), + ) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&empty_set, &empty_set.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&standard_empty_set, &standard_empty_set.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&empty_set, "hashCode", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&standard_empty_set, "hashCode", "()I", ()).await?, 0); let element: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (11,)).await?.into(); - let element_hash: i32 = jvm.invoke_virtual(&element, "hashCode", "()I", ()).await?; + let element_hash: i32 = jvm + .invoke_virtual(&element, &element.class_definition().name(), "hashCode", "()I", ()) + .await?; let copies: ClassInstanceRef = jvm .invoke_static( "java/util/Collections", @@ -1261,20 +1492,44 @@ async fn test_coll_07_immutable_equals_and_hash_code_match_standard_collections( .await?; let peer_list = integer_list(&jvm, &[11, 11]).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&copies, "equals", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &copies, + &copies.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&copies, "equals", "(Ljava/lang/Object;)Z", (peer_list.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &copies, + &copies.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (peer_list.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&peer_list, "equals", "(Ljava/lang/Object;)Z", (copies.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &peer_list, + &peer_list.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (copies.clone(),) + ) + .await? ); - let copies_hash: i32 = jvm.invoke_virtual(&copies, "hashCode", "()I", ()).await?; + let copies_hash: i32 = jvm + .invoke_virtual(&copies, &copies.class_definition().name(), "hashCode", "()I", ()) + .await?; assert_eq!(copies_hash, 31i32.wrapping_mul(31 + element_hash).wrapping_add(element_hash)); - assert_eq!(jvm.invoke_virtual::<_, i32>(&copies, "hashCode", "()I", ()).await?, copies_hash); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&copies, &copies.class_definition().name(), "hashCode", "()I", ()) + .await?, + copies_hash + ); let one_copy: ClassInstanceRef = jvm .invoke_static( "java/util/Collections", @@ -1284,10 +1539,20 @@ async fn test_coll_07_immutable_equals_and_hash_code_match_standard_collections( ) .await?; assert!( - !jvm.invoke_virtual::<_, bool>(&copies, "equals", "(Ljava/lang/Object;)Z", (one_copy.clone(),)) + !jvm.invoke_virtual::<_, bool>( + &copies, + &copies.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (one_copy.clone(),) + ) + .await? + ); + assert_ne!( + copies_hash, + jvm.invoke_virtual::<_, i32>(&one_copy, &one_copy.class_definition().name(), "hashCode", "()I", ()) .await? ); - assert_ne!(copies_hash, jvm.invoke_virtual::<_, i32>(&one_copy, "hashCode", "()I", ()).await?); let singleton: ClassInstanceRef = jvm .invoke_static( @@ -1299,23 +1564,55 @@ async fn test_coll_07_immutable_equals_and_hash_code_match_standard_collections( .await?; let peer_set: ClassInstanceRef = jvm.new_class("java/util/HashSet", "()V", ()).await?.into(); let peer_element: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (11,)).await?.into(); - let _: bool = jvm.invoke_virtual(&peer_set, "add", "(Ljava/lang/Object;)Z", (peer_element,)).await?; + let _: bool = jvm + .invoke_virtual( + &peer_set, + &peer_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (peer_element,), + ) + .await?; assert!( - !jvm.invoke_virtual::<_, bool>(&singleton, "equals", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &singleton, + &singleton.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&singleton, "equals", "(Ljava/lang/Object;)Z", (peer_set.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &singleton, + &singleton.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (peer_set.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&peer_set, "equals", "(Ljava/lang/Object;)Z", (singleton.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &peer_set, + &peer_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (singleton.clone(),) + ) + .await? ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&singleton, "hashCode", "()I", ()).await?, element_hash); assert_eq!( - jvm.invoke_virtual::<_, i32>(&singleton, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&peer_set, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&singleton, &singleton.class_definition().name(), "hashCode", "()I", ()) + .await?, + element_hash + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&singleton, &singleton.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&peer_set, &peer_set.class_definition().name(), "hashCode", "()I", ()) + .await? ); let null_copies: ClassInstanceRef = jvm @@ -1329,18 +1626,40 @@ async fn test_coll_07_immutable_equals_and_hash_code_match_standard_collections( let null_peer_list: ClassInstanceRef = jvm.new_class("java/util/ArrayList", "()V", ()).await?.into(); for _ in 0..2 { let _: bool = jvm - .invoke_virtual(&null_peer_list, "add", "(Ljava/lang/Object;)Z", (null.clone(),)) + .invoke_virtual( + &null_peer_list, + &null_peer_list.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (null.clone(),), + ) .await?; } assert!( - jvm.invoke_virtual::<_, bool>(&null_copies, "equals", "(Ljava/lang/Object;)Z", (null_peer_list.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &null_copies, + &null_copies.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_peer_list.clone(),), + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&null_peer_list, "equals", "(Ljava/lang/Object;)Z", (null_copies.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &null_peer_list, + &null_peer_list.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_copies.clone(),), + ) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&null_copies, &null_copies.class_definition().name(), "hashCode", "()I", ()) + .await?, + 961 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&null_copies, "hashCode", "()I", ()).await?, 961); let null_singleton: ClassInstanceRef = jvm .invoke_static( @@ -1352,18 +1671,44 @@ async fn test_coll_07_immutable_equals_and_hash_code_match_standard_collections( .await?; let null_peer_set: ClassInstanceRef = jvm.new_class("java/util/HashSet", "()V", ()).await?.into(); let _: bool = jvm - .invoke_virtual(&null_peer_set, "add", "(Ljava/lang/Object;)Z", (null.clone(),)) + .invoke_virtual( + &null_peer_set, + &null_peer_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (null.clone(),), + ) .await?; assert!( - jvm.invoke_virtual::<_, bool>(&null_singleton, "equals", "(Ljava/lang/Object;)Z", (null_peer_set.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &null_singleton, + &null_singleton.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_peer_set.clone(),), + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&null_peer_set, "equals", "(Ljava/lang/Object;)Z", (null_singleton.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &null_peer_set, + &null_peer_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_singleton.clone(),), + ) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&null_singleton, &null_singleton.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&null_peer_set, &null_peer_set.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&null_singleton, "hashCode", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&null_peer_set, "hashCode", "()I", ()).await?, 0); Ok(()) } @@ -1386,11 +1731,17 @@ async fn test_coll_07_abstract_set_equals_catches_only_jdk_compatibility_excepti .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&incompatible, "equals", "(Ljava/lang/Object;)Z", (peer.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &incompatible, + &incompatible.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (peer.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&peer, "equals", "(Ljava/lang/Object;)Z", (incompatible,)) + jvm.invoke_virtual::<_, bool>(&peer, &peer.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (incompatible,)) .await? ); @@ -1408,19 +1759,39 @@ async fn test_coll_07_abstract_set_equals_catches_only_jdk_compatibility_excepti .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&null_rejecting, "equals", "(Ljava/lang/Object;)Z", (null_peer.clone(),),) - .await? + !jvm.invoke_virtual::<_, bool>( + &null_rejecting, + &null_rejecting.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_peer.clone(),), + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&null_peer, "equals", "(Ljava/lang/Object;)Z", (null_rejecting,)) - .await? + jvm.invoke_virtual::<_, bool>( + &null_peer, + &null_peer.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_rejecting,) + ) + .await? ); let unexpected: ClassInstanceRef = jvm .new_class("CollectionsExceptionalSet", "(Ljava/lang/Object;I)V", (value, 2)) .await? .into(); - let result: Result = jvm.invoke_virtual(&unexpected, "equals", "(Ljava/lang/Object;)Z", (peer,)).await; + let result: Result = jvm + .invoke_virtual( + &unexpected, + &unexpected.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (peer,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("AbstractSet.equals must propagate non-compatibility exceptions"); }; @@ -1448,8 +1819,14 @@ async fn test_coll_07_singleton_set_equals_uses_other_element_direction() -> Res .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&accepting_singleton, "equals", "(Ljava/lang/Object;)Z", (rejecting_peer,),) - .await? + !jvm.invoke_virtual::<_, bool>( + &accepting_singleton, + &accepting_singleton.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (rejecting_peer,), + ) + .await? ); let rejecting_singleton: ClassInstanceRef = jvm @@ -1460,8 +1837,14 @@ async fn test_coll_07_singleton_set_equals_uses_other_element_direction() -> Res .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&rejecting_singleton, "equals", "(Ljava/lang/Object;)Z", (accepting_peer,),) - .await? + jvm.invoke_virtual::<_, bool>( + &rejecting_singleton, + &rejecting_singleton.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (accepting_peer,), + ) + .await? ); Ok(()) @@ -1732,8 +2115,14 @@ async fn test_coll_08_exact_descriptors_access_and_null_factories() -> Result<() let wrapper_class = jvm.resolve_class(name).await?.java_class(); assert_eq!( - jvm.invoke_virtual::<_, bool>(&serializable, "isAssignableFrom", "(Ljava/lang/Class;)Z", (wrapper_class,),) - .await?, + jvm.invoke_virtual::<_, bool>( + &serializable, + &serializable.class_definition().name(), + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + (wrapper_class,), + ) + .await?, *is_serializable, "{name} Serializable" ); @@ -1764,35 +2153,87 @@ async fn test_coll_08_unmodifiable_collection_is_live_identity_based_and_always_ .await?; assert_ne!(wrapper.identity(), nested.identity()); assert!( - jvm.invoke_virtual::<_, bool>(&wrapper, "equals", "(Ljava/lang/Object;)Z", (wrapper.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &wrapper, + &wrapper.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (wrapper.clone(),) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&wrapper, "equals", "(Ljava/lang/Object;)Z", (backing.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &wrapper, + &wrapper.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (backing.clone(),) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&wrapper, "equals", "(Ljava/lang/Object;)Z", (nested.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &wrapper, + &wrapper.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (nested.clone(),) + ) + .await? ); let null: ClassInstanceRef = None.into(); assert!( - !jvm.invoke_virtual::<_, bool>(&wrapper, "equals", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &wrapper, + &wrapper.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); let value: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (2,)).await?.into(); - let _: bool = jvm.invoke_virtual(&backing, "add", "(Ljava/lang/Object;)Z", (value.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&wrapper, "size", "()I", ()).await?, 2); + let _: bool = jvm + .invoke_virtual( + &backing, + &backing.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (value.clone(),), + ) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&wrapper, &wrapper.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); assert!( - jvm.invoke_virtual::<_, bool>(&wrapper, "contains", "(Ljava/lang/Object;)Z", (value.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &wrapper, + &wrapper.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (value.clone(),) + ) + .await? ); - let backing_text: ClassInstanceRef = jvm.invoke_virtual(&backing, "toString", "()Ljava/lang/String;", ()).await?; - let wrapper_text: ClassInstanceRef = jvm.invoke_virtual(&wrapper, "toString", "()Ljava/lang/String;", ()).await?; + let backing_text: ClassInstanceRef = jvm + .invoke_virtual(&backing, &backing.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; + let wrapper_text: ClassInstanceRef = jvm + .invoke_virtual(&wrapper, &wrapper.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&wrapper_text, "equals", "(Ljava/lang/Object;)Z", (backing_text,)) - .await? + jvm.invoke_virtual::<_, bool>( + &wrapper_text, + &wrapper_text.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (backing_text,) + ) + .await? ); let mut destination: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/Object;", 3).await?.into(); @@ -1800,7 +2241,13 @@ async fn test_coll_08_unmodifiable_collection_is_live_identity_based_and_always_ jvm.store_array(&mut destination, 2, core::iter::once(sentinel)).await?; let destination_identity = destination.identity(); let result: ClassInstanceRef> = jvm - .invoke_virtual(&wrapper, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (destination,)) + .invoke_virtual( + &wrapper, + &wrapper.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (destination,), + ) .await?; assert_eq!(result.identity(), destination_identity); assert!(jvm.load_array::>(&result, 2, 1).await?[0].is_null()); @@ -1810,7 +2257,9 @@ async fn test_coll_08_unmodifiable_collection_is_live_identity_based_and_always_ ("add", null.clone()), ("remove", jvm.new_class("java/lang/Integer", "(I)V", (404,)).await?.into()), ] { - let result: Result = jvm.invoke_virtual(&wrapper, name, "(Ljava/lang/Object;)Z", (argument,)).await; + let result: Result = jvm + .invoke_virtual(&wrapper, &wrapper.class_definition().name(), name, "(Ljava/lang/Object;)Z", (argument,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{name} must throw even when no change is possible"); }; @@ -1824,7 +2273,15 @@ async fn test_coll_08_unmodifiable_collection_is_live_identity_based_and_always_ ("retainAll", wrapper.clone()), ("retainAll", null.clone()), ] { - let result: Result = jvm.invoke_virtual(&wrapper, name, "(Ljava/util/Collection;)Z", (argument,)).await; + let result: Result = jvm + .invoke_virtual( + &wrapper, + &wrapper.class_definition().name(), + name, + "(Ljava/util/Collection;)Z", + (argument,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{name} must throw before no-op or null handling"); }; @@ -1839,20 +2296,30 @@ async fn test_coll_08_unmodifiable_collection_is_live_identity_based_and_always_ (empty,), ) .await?; - let clear: Result<()> = jvm.invoke_virtual(&empty_wrapper, "clear", "()V", ()).await; + let clear: Result<()> = jvm + .invoke_virtual(&empty_wrapper, &empty_wrapper.class_definition().name(), "clear", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = clear else { panic!("clear on an empty wrapper must throw"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&wrapper, "iterator", "()Ljava/util/Iterator;", ()).await?; - let remove: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&wrapper, &wrapper.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let remove: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = remove else { panic!("iterator.remove before next must throw UOE"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let remove: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let remove: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = remove else { panic!("iterator.remove after next must throw UOE"); }; @@ -1883,116 +2350,213 @@ async fn test_coll_08_unmodifiable_list_delegates_value_contract_and_wraps_sub_l .await?; assert_ne!(list.identity(), nested.identity()); assert!( - jvm.invoke_virtual::<_, bool>(&list, "equals", "(Ljava/lang/Object;)Z", (backing.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &list, + &list.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (backing.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&nested, "equals", "(Ljava/lang/Object;)Z", (list.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &nested, + &nested.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (list.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&list, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&backing, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&backing, &backing.class_definition().name(), "hashCode", "()I", ()) + .await? ); let null: ClassInstanceRef = None.into(); assert!( - !jvm.invoke_virtual::<_, bool>(&list, "equals", "(Ljava/lang/Object;)Z", (null.clone(),)) + !jvm.invoke_virtual::<_, bool>(&list, &list.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (null.clone(),)) .await? ); - let backing_text: ClassInstanceRef = jvm.invoke_virtual(&backing, "toString", "()Ljava/lang/String;", ()).await?; - let list_text: ClassInstanceRef = jvm.invoke_virtual(&list, "toString", "()Ljava/lang/String;", ()).await?; + let backing_text: ClassInstanceRef = jvm + .invoke_virtual(&backing, &backing.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; + let list_text: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&list_text, "equals", "(Ljava/lang/Object;)Z", (backing_text,)) - .await? + jvm.invoke_virtual::<_, bool>( + &list_text, + &list_text.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (backing_text,) + ) + .await? ); let replacement: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (20,)).await?.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(&backing, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (1, replacement.clone())) + .invoke_virtual( + &backing, + &backing.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (1, replacement.clone()), + ) .await?; assert_eq!(integer_values(&jvm, &list).await?, vec![1, 20, 3]); - let sub_list: ClassInstanceRef = jvm.invoke_virtual(&list, "subList", "(II)Ljava/util/List;", (0, 2)).await?; - let nested_sub_list: ClassInstanceRef = jvm.invoke_virtual(&sub_list, "subList", "(II)Ljava/util/List;", (1, 2)).await?; + let sub_list: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "subList", "(II)Ljava/util/List;", (0, 2)) + .await?; + let nested_sub_list: ClassInstanceRef = jvm + .invoke_virtual(&sub_list, &sub_list.class_definition().name(), "subList", "(II)Ljava/util/List;", (1, 2)) + .await?; assert_eq!(integer_values(&jvm, &sub_list).await?, vec![1, 20]); assert_eq!(integer_values(&jvm, &nested_sub_list).await?, vec![20]); let changed: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (21,)).await?.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(&backing, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (1, changed.clone())) + .invoke_virtual( + &backing, + &backing.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (1, changed.clone()), + ) .await?; assert_eq!(integer_values(&jvm, &nested_sub_list).await?, vec![21]); let set: Result> = jvm - .invoke_virtual(&list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (-1, changed.clone())) + .invoke_virtual( + &list, + &list.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (-1, changed.clone()), + ) .await; let Err(JavaError::JavaException(exception)) = set else { panic!("set with invalid index must throw UOE first"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let add: Result<()> = jvm.invoke_virtual(&list, "add", "(ILjava/lang/Object;)V", (-1, changed.clone())).await; + let add: Result<()> = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "add", + "(ILjava/lang/Object;)V", + (-1, changed.clone()), + ) + .await; let Err(JavaError::JavaException(exception)) = add else { panic!("add with invalid index must throw UOE first"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let remove: Result> = jvm.invoke_virtual(&list, "remove", "(I)Ljava/lang/Object;", (-1,)).await; + let remove: Result> = jvm + .invoke_virtual(&list, &list.class_definition().name(), "remove", "(I)Ljava/lang/Object;", (-1,)) + .await; let Err(JavaError::JavaException(exception)) = remove else { panic!("remove with invalid index must throw UOE first"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); let add_all: Result = jvm - .invoke_virtual(&list, "addAll", "(ILjava/util/Collection;)Z", (-1, null.clone())) + .invoke_virtual( + &list, + &list.class_definition().name(), + "addAll", + "(ILjava/util/Collection;)Z", + (-1, null.clone()), + ) .await; let Err(JavaError::JavaException(exception)) = add_all else { panic!("indexed addAll must throw UOE before index and null validation"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); let empty = integer_list(&jvm, &[]).await?; - let add_all: Result = jvm.invoke_virtual(&list, "addAll", "(ILjava/util/Collection;)Z", (0, empty)).await; + let add_all: Result = jvm + .invoke_virtual(&list, &list.class_definition().name(), "addAll", "(ILjava/util/Collection;)Z", (0, empty)) + .await; let Err(JavaError::JavaException(exception)) = add_all else { panic!("indexed addAll of an empty collection must throw"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); let sub_set: Result> = jvm - .invoke_virtual(&sub_list, "set", "(ILjava/lang/Object;)Ljava/lang/Object;", (0, changed.clone())) + .invoke_virtual( + &sub_list, + &sub_list.class_definition().name(), + "set", + "(ILjava/lang/Object;)Ljava/lang/Object;", + (0, changed.clone()), + ) .await; let Err(JavaError::JavaException(exception)) = sub_set else { panic!("subList must remain unmodifiable"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "()Ljava/util/ListIterator;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "nextIndex", "()I", ()).await?, 0); + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "listIterator", "()Ljava/util/ListIterator;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "nextIndex", "()I", ()) + .await?, + 0 + ); for (name, descriptor, argument) in [ ("set", "(Ljava/lang/Object;)V", changed.clone()), ("add", "(Ljava/lang/Object;)V", changed.clone()), ] { - let result: Result<()> = jvm.invoke_virtual(&iterator, name, descriptor, (argument,)).await; + let result: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), name, descriptor, (argument,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("listIterator.{name} before next must throw UOE"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); } - let remove: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let remove: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = remove else { panic!("listIterator.remove before next must throw UOE"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let first: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "intValue", "()I", ()).await?, 1); - assert!(jvm.invoke_virtual::<_, bool>(&iterator, "hasPrevious", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "previousIndex", "()I", ()).await?, 0); + let first: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "intValue", "()I", ()) + .await?, + 1 + ); + assert!( + jvm.invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasPrevious", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "previousIndex", "()I", ()) + .await?, + 0 + ); for (name, descriptor, argument) in [ ("set", "(Ljava/lang/Object;)V", changed.clone()), ("add", "(Ljava/lang/Object;)V", changed), ] { - let result: Result<()> = jvm.invoke_virtual(&iterator, name, descriptor, (argument,)).await; + let result: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), name, descriptor, (argument,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("listIterator.{name} after next must throw UOE"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); } - let remove: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let remove: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = remove else { panic!("listIterator.remove after next must throw UOE"); }; @@ -2007,7 +2571,9 @@ async fn test_coll_08_unmodifiable_set_and_map_views_are_live_and_always_unmodif let set: ClassInstanceRef = jvm.new_class("java/util/HashSet", "()V", ()).await?.into(); let first: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (1,)).await?.into(); let second: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (2,)).await?.into(); - let _: bool = jvm.invoke_virtual(&set, "add", "(Ljava/lang/Object;)Z", (first.clone(),)).await?; + let _: bool = jvm + .invoke_virtual(&set, &set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (first.clone(),)) + .await?; let wrapped_set: ClassInstanceRef = jvm .invoke_static( "java/util/Collections", @@ -2026,23 +2592,49 @@ async fn test_coll_08_unmodifiable_set_and_map_views_are_live_and_always_unmodif .await?; assert_ne!(wrapped_set.identity(), nested_set.identity()); assert!( - jvm.invoke_virtual::<_, bool>(&wrapped_set, "equals", "(Ljava/lang/Object;)Z", (set.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &wrapped_set, + &wrapped_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (set.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&wrapped_set, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&set, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&wrapped_set, &wrapped_set.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&set, &set.class_definition().name(), "hashCode", "()I", ()) + .await? ); let null: ClassInstanceRef = None.into(); assert!( - !jvm.invoke_virtual::<_, bool>(&wrapped_set, "equals", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &wrapped_set, + &wrapped_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? + ); + let _: bool = jvm + .invoke_virtual(&set, &set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (second.clone(),)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&wrapped_set, &wrapped_set.class_definition().name(), "size", "()I", ()) + .await?, + 2 ); - let _: bool = jvm.invoke_virtual(&set, "add", "(Ljava/lang/Object;)Z", (second.clone(),)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&wrapped_set, "size", "()I", ()).await?, 2); let absent: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (404,)).await?.into(); let remove: Result = jvm - .invoke_virtual(&wrapped_set, "remove", "(Ljava/lang/Object;)Z", (absent.clone(),)) + .invoke_virtual( + &wrapped_set, + &wrapped_set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (absent.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = remove else { panic!("set removal of an absent element must throw"); @@ -2054,6 +2646,7 @@ async fn test_coll_08_unmodifiable_set_and_map_views_are_live_and_always_unmodif let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (first.clone(), value.clone()), @@ -2077,34 +2670,94 @@ async fn test_coll_08_unmodifiable_set_and_map_views_are_live_and_always_unmodif .await?; assert_ne!(wrapped_map.identity(), nested_map.identity()); assert!( - jvm.invoke_virtual::<_, bool>(&wrapped_map, "equals", "(Ljava/lang/Object;)Z", (map.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &wrapped_map, + &wrapped_map.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (map.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&nested_map, "equals", "(Ljava/lang/Object;)Z", (wrapped_map.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &nested_map, + &nested_map.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (wrapped_map.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&wrapped_map, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&map, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&wrapped_map, &wrapped_map.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&map, &map.class_definition().name(), "hashCode", "()I", ()) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&wrapped_map, "equals", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &wrapped_map, + &wrapped_map.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); - let map_text: ClassInstanceRef = jvm.invoke_virtual(&map, "toString", "()Ljava/lang/String;", ()).await?; - let wrapped_text: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "toString", "()Ljava/lang/String;", ()).await?; + let map_text: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; + let wrapped_text: ClassInstanceRef = jvm + .invoke_virtual( + &wrapped_map, + &wrapped_map.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&wrapped_text, "equals", "(Ljava/lang/Object;)Z", (map_text,)) - .await? + jvm.invoke_virtual::<_, bool>( + &wrapped_text, + &wrapped_text.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (map_text,) + ) + .await? ); - let keys: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "keySet", "()Ljava/util/Set;", ()).await?; - let same_keys: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "keySet", "()Ljava/util/Set;", ()).await?; - let values: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "values", "()Ljava/util/Collection;", ()).await?; - let same_values: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "values", "()Ljava/util/Collection;", ()).await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "entrySet", "()Ljava/util/Set;", ()).await?; - let same_entries: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let keys: ClassInstanceRef = jvm + .invoke_virtual(&wrapped_map, &wrapped_map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let same_keys: ClassInstanceRef = jvm + .invoke_virtual(&wrapped_map, &wrapped_map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let values: ClassInstanceRef = jvm + .invoke_virtual( + &wrapped_map, + &wrapped_map.class_definition().name(), + "values", + "()Ljava/util/Collection;", + (), + ) + .await?; + let same_values: ClassInstanceRef = jvm + .invoke_virtual( + &wrapped_map, + &wrapped_map.class_definition().name(), + "values", + "()Ljava/util/Collection;", + (), + ) + .await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&wrapped_map, &wrapped_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let same_entries: ClassInstanceRef = jvm + .invoke_virtual(&wrapped_map, &wrapped_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; assert_eq!(keys.identity(), same_keys.identity()); assert_eq!(values.identity(), same_values.identity()); assert_eq!(entries.identity(), same_entries.identity()); @@ -2112,21 +2765,37 @@ async fn test_coll_08_unmodifiable_set_and_map_views_are_live_and_always_unmodif let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (second.clone(), second_value.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&keys, "size", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&keys, &keys.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); assert!( - jvm.invoke_virtual::<_, bool>(&values, "contains", "(Ljava/lang/Object;)Z", (second_value,)) - .await? + jvm.invoke_virtual::<_, bool>( + &values, + &values.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (second_value,) + ) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&entries, &entries.class_definition().name(), "size", "()I", ()) + .await?, + 2 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&entries, "size", "()I", ()).await?, 2); let put: Result> = jvm .invoke_virtual( &wrapped_map, + &wrapped_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null.clone(), null.clone()), @@ -2137,7 +2806,13 @@ async fn test_coll_08_unmodifiable_set_and_map_views_are_live_and_always_unmodif }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); let remove: Result> = jvm - .invoke_virtual(&wrapped_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (absent.clone(),)) + .invoke_virtual( + &wrapped_map, + &wrapped_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (absent.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = remove else { panic!("map.remove of absent key must throw"); @@ -2148,7 +2823,15 @@ async fn test_coll_08_unmodifiable_set_and_map_views_are_live_and_always_unmodif wrapped_map.clone(), null.clone(), ] { - let put_all: Result<()> = jvm.invoke_virtual(&wrapped_map, "putAll", "(Ljava/util/Map;)V", (source,)).await; + let put_all: Result<()> = jvm + .invoke_virtual( + &wrapped_map, + &wrapped_map.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (source,), + ) + .await; let Err(JavaError::JavaException(exception)) = put_all else { panic!("map.putAll must throw for empty, self, and null inputs"); }; @@ -2163,7 +2846,9 @@ async fn test_coll_08_unmodifiable_set_and_map_views_are_live_and_always_unmodif (empty_map,), ) .await?; - let clear: Result<()> = jvm.invoke_virtual(&empty_wrapper, "clear", "()V", ()).await; + let clear: Result<()> = jvm + .invoke_virtual(&empty_wrapper, &empty_wrapper.class_definition().name(), "clear", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = clear else { panic!("map.clear on empty map must throw"); }; @@ -2171,32 +2856,52 @@ async fn test_coll_08_unmodifiable_set_and_map_views_are_live_and_always_unmodif let empty_collection = integer_list(&jvm, &[]).await?; for view in [keys, values, entries] { - let add: Result = jvm.invoke_virtual(&view, "add", "(Ljava/lang/Object;)Z", (null.clone(),)).await; + let add: Result = jvm + .invoke_virtual(&view, &view.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (null.clone(),)) + .await; let Err(JavaError::JavaException(exception)) = add else { panic!("map view add must throw"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let remove: Result = jvm.invoke_virtual(&view, "remove", "(Ljava/lang/Object;)Z", (absent.clone(),)).await; + let remove: Result = jvm + .invoke_virtual( + &view, + &view.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (absent.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = remove else { panic!("map view remove of absent value must throw"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); for name in ["addAll", "removeAll", "retainAll"] { let bulk: Result = jvm - .invoke_virtual(&view, name, "(Ljava/util/Collection;)Z", (empty_collection.clone(),)) + .invoke_virtual( + &view, + &view.class_definition().name(), + name, + "(Ljava/util/Collection;)Z", + (empty_collection.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = bulk else { panic!("map view {name} must throw for an empty input"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); } - let clear: Result<()> = jvm.invoke_virtual(&view, "clear", "()V", ()).await; + let clear: Result<()> = jvm.invoke_virtual(&view, &view.class_definition().name(), "clear", "()V", ()).await; let Err(JavaError::JavaException(exception)) = clear else { panic!("map view clear must throw"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/UnsupportedOperationException")); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&view, "iterator", "()Ljava/util/Iterator;", ()).await?; - let remove: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&view, &view.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let remove: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = remove else { panic!("map view iterator.remove must throw before next"); }; @@ -2215,14 +2920,27 @@ async fn test_coll_08_unmodifiable_entry_set_wraps_iterator_and_all_array_result let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), original), ) .await?; - let raw_entries: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - let raw_iterator: ClassInstanceRef = jvm.invoke_virtual(&raw_entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let raw_entry: ClassInstanceRef = jvm.invoke_virtual(&raw_iterator, "next", "()Ljava/lang/Object;", ()).await?; + let raw_entries: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let raw_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &raw_entries, + &raw_entries.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let raw_entry: ClassInstanceRef = jvm + .invoke_virtual(&raw_iterator, &raw_iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let wrapped_map: ClassInstanceRef = jvm .invoke_static( @@ -2232,49 +2950,104 @@ async fn test_coll_08_unmodifiable_entry_set_wraps_iterator_and_all_array_result (map.clone(),), ) .await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&wrapped_map, &wrapped_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&entries, "contains", "(Ljava/lang/Object;)Z", (raw_entry.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (raw_entry.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&entries, "containsAll", "(Ljava/util/Collection;)Z", (raw_entries.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "containsAll", + "(Ljava/util/Collection;)Z", + (raw_entries.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&entries, "equals", "(Ljava/lang/Object;)Z", (raw_entries.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (raw_entries.clone(),) + ) + .await? ); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let wrapped_entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let wrapped_entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!( wrapped_entry.class_definition().name(), "java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry" ); assert!( - jvm.invoke_virtual::<_, bool>(&wrapped_entry, "equals", "(Ljava/lang/Object;)Z", (raw_entry.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &wrapped_entry, + &wrapped_entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (raw_entry.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&wrapped_entry, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&raw_entry, "hashCode", "()I", ()).await? - ); - let null_entry: ClassInstanceRef = None.into(); - assert!( - !jvm.invoke_virtual::<_, bool>(&wrapped_entry, "equals", "(Ljava/lang/Object;)Z", (null_entry,),) + jvm.invoke_virtual::<_, i32>(&wrapped_entry, &wrapped_entry.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&raw_entry, &raw_entry.class_definition().name(), "hashCode", "()I", ()) .await? ); - let raw_text: ClassInstanceRef = jvm.invoke_virtual(&raw_entry, "toString", "()Ljava/lang/String;", ()).await?; - let wrapped_text: ClassInstanceRef = jvm.invoke_virtual(&wrapped_entry, "toString", "()Ljava/lang/String;", ()).await?; + let null_entry: ClassInstanceRef = None.into(); assert!( - jvm.invoke_virtual::<_, bool>(&wrapped_text, "equals", "(Ljava/lang/Object;)Z", (raw_text,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &wrapped_entry, + &wrapped_entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_entry,), + ) + .await? ); - let replacement = JavaLangString::from_rust_string(&jvm, "after").await?; - let set_value: Result> = jvm + let raw_text: ClassInstanceRef = jvm + .invoke_virtual(&raw_entry, &raw_entry.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; + let wrapped_text: ClassInstanceRef = jvm .invoke_virtual( &wrapped_entry, + &wrapped_entry.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; + assert!( + jvm.invoke_virtual::<_, bool>( + &wrapped_text, + &wrapped_text.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (raw_text,) + ) + .await? + ); + let replacement = JavaLangString::from_rust_string(&jvm, "after").await?; + let set_value: Result> = jvm + .invoke_virtual( + &wrapped_entry, + &wrapped_entry.class_definition().name(), "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (replacement.clone(),), @@ -2288,18 +3061,35 @@ async fn test_coll_08_unmodifiable_entry_set_wraps_iterator_and_all_array_result let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, replacement.clone()), ) .await?; - let live_value: ClassInstanceRef = jvm.invoke_virtual(&wrapped_entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let live_value: ClassInstanceRef = jvm + .invoke_virtual( + &wrapped_entry, + &wrapped_entry.class_definition().name(), + "getValue", + "()Ljava/lang/Object;", + (), + ) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&live_value, "equals", "(Ljava/lang/Object;)Z", (replacement,)) - .await? + jvm.invoke_virtual::<_, bool>( + &live_value, + &live_value.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (replacement,) + ) + .await? ); - let array: ClassInstanceRef> = jvm.invoke_virtual(&entries, "toArray", "()[Ljava/lang/Object;", ()).await?; + let array: ClassInstanceRef> = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let array_entry = jvm.load_array::>(&array, 0, 1).await?[0].clone(); assert_eq!( array_entry.class_definition().name(), @@ -2307,7 +3097,13 @@ async fn test_coll_08_unmodifiable_entry_set_wraps_iterator_and_all_array_result ); let null_value: ClassInstanceRef = None.into(); let set_value: Result> = jvm - .invoke_virtual(&array_entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (null_value,)) + .invoke_virtual( + &array_entry, + &array_entry.class_definition().name(), + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (null_value,), + ) .await; let Err(JavaError::JavaException(exception)) = set_value else { panic!("entry returned by toArray must be unmodifiable"); @@ -2318,7 +3114,13 @@ async fn test_coll_08_unmodifiable_entry_set_wraps_iterator_and_all_array_result jvm.store_array(&mut typed_destination, 1, core::iter::once(raw_entry.clone())).await?; let destination_identity = typed_destination.identity(); let typed: ClassInstanceRef> = jvm - .invoke_virtual(&entries, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (typed_destination,)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (typed_destination,), + ) .await?; assert_eq!(typed.identity(), destination_identity); let typed_values = jvm.load_array::>(&typed, 0, 2).await?; @@ -2330,7 +3132,13 @@ async fn test_coll_08_unmodifiable_entry_set_wraps_iterator_and_all_array_result let small: ClassInstanceRef> = jvm.instantiate_array("Ljava/util/Map$Entry;", 0).await?.into(); let grown: ClassInstanceRef> = jvm - .invoke_virtual(&entries, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (small,)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (small,), + ) .await?; assert_eq!(jvm.array_length(&grown).await?, 1); assert_eq!(grown.class_definition().name(), "[Ljava/util/Map$Entry;"); @@ -2343,7 +3151,13 @@ async fn test_coll_08_unmodifiable_entry_set_wraps_iterator_and_all_array_result let null_array: ClassInstanceRef> = None.into(); let result: Result>> = jvm - .invoke_virtual(&entries, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (null_array,)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (null_array,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("typed entry toArray(null) must throw"); @@ -2352,7 +3166,13 @@ async fn test_coll_08_unmodifiable_entry_set_wraps_iterator_and_all_array_result let incompatible: ClassInstanceRef> = jvm.instantiate_array("Ljava/util/HashMap$Entry;", 2).await?.into(); let result: Result>> = jvm - .invoke_virtual(&entries, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (incompatible.clone(),)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (incompatible.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("concrete mutable-entry array must reject wrapped entries"); @@ -2398,8 +3218,14 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&wrapped_entry, "equals", "(Ljava/lang/Object;)Z", (candidate_entry.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &wrapped_entry, + &wrapped_entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (candidate_entry.clone(),) + ) + .await? ); assert_eq!(jvm.get_field::(&backing_entry, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&candidate_entry, "keyCalls", "I").await?, 1); @@ -2437,8 +3263,14 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&wrapped_entry, "equals", "(Ljava/lang/Object;)Z", (candidate_entry.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &wrapped_entry, + &wrapped_entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (candidate_entry.clone(),) + ) + .await? ); assert_eq!(jvm.get_field::(&backing_entry, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&backing_entry, "valueCalls", "I").await?, 1); @@ -2451,7 +3283,13 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi let replacement: ClassInstanceRef = jvm.new_class("java/lang/Object", "()V", ()).await?.into(); let result: Result> = jvm - .invoke_virtual(&wrapped_entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (replacement,)) + .invoke_virtual( + &wrapped_entry, + &wrapped_entry.class_definition().name(), + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (replacement,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("wrapped custom entry.setValue must throw"); @@ -2484,7 +3322,13 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi .await? .into(); let result: Result = jvm - .invoke_virtual(&throwing_key_wrapper, "equals", "(Ljava/lang/Object;)Z", (untouched_candidate.clone(),)) + .invoke_virtual( + &throwing_key_wrapper, + &throwing_key_wrapper.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (untouched_candidate.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("backing getKey exception must propagate"); @@ -2511,7 +3355,13 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi .await? .into(); let result: Result = jvm - .invoke_virtual(&throwing_equals_wrapper, "equals", "(Ljava/lang/Object;)Z", (candidate_entry.clone(),)) + .invoke_virtual( + &throwing_equals_wrapper, + &throwing_equals_wrapper.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (candidate_entry.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("backing key.equals exception must propagate"); @@ -2531,6 +3381,7 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi let result: Result = jvm .invoke_virtual( &wrapped_entry, + &wrapped_entry.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (required_throwing_value_entry.clone(),), @@ -2549,6 +3400,7 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (map_key.clone(), map_value.clone()), @@ -2557,7 +3409,9 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi let wrapped_map: ClassInstanceRef = jvm .invoke_static("java/util/Collections", "unmodifiableMap", "(Ljava/util/Map;)Ljava/util/Map;", (map,)) .await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&wrapped_map, &wrapped_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; let matching: ClassInstanceRef = jvm .new_class( "CollectionsEntryProbe", @@ -2567,8 +3421,14 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&entries, "contains", "(Ljava/lang/Object;)Z", (matching.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (matching.clone(),) + ) + .await? ); assert_eq!(jvm.get_field::(&matching, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&matching, "valueCalls", "I").await?, 1); @@ -2584,8 +3444,14 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&entries, "contains", "(Ljava/lang/Object;)Z", (missing.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (missing.clone(),) + ) + .await? ); assert_eq!(jvm.get_field::(&missing, "keyCalls", "I").await?, 1); assert_eq!(jvm.get_field::(&missing, "valueCalls", "I").await?, 0); @@ -2600,7 +3466,13 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi .await? .into(); let result: Result = jvm - .invoke_virtual(&entries, "contains", "(Ljava/lang/Object;)Z", (required_throwing_value.clone(),)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (required_throwing_value.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("contains must propagate getValue failure after finding the key"); @@ -2618,7 +3490,13 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi .await? .into(); let result: Result = jvm - .invoke_virtual(&entries, "contains", "(Ljava/lang/Object;)Z", (throwing_key.clone(),)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (throwing_key.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("contains must propagate getKey failure"); @@ -2637,17 +3515,41 @@ async fn test_coll_08_unmodifiable_entry_equals_and_contains_preserve_jdk_orderi .into(); let candidates: ClassInstanceRef = jvm.new_class("java/util/ArrayList", "()V", ()).await?.into(); let _: bool = jvm - .invoke_virtual(&candidates, "add", "(Ljava/lang/Object;)Z", (matching.clone(),)) + .invoke_virtual( + &candidates, + &candidates.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (matching.clone(),), + ) .await?; let _: bool = jvm - .invoke_virtual(&candidates, "add", "(Ljava/lang/Object;)Z", (missing.clone(),)) + .invoke_virtual( + &candidates, + &candidates.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (missing.clone(),), + ) .await?; let _: bool = jvm - .invoke_virtual(&candidates, "add", "(Ljava/lang/Object;)Z", (never_reached.clone(),)) + .invoke_virtual( + &candidates, + &candidates.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (never_reached.clone(),), + ) .await?; assert!( - !jvm.invoke_virtual::<_, bool>(&entries, "containsAll", "(Ljava/util/Collection;)Z", (candidates,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "containsAll", + "(Ljava/util/Collection;)Z", + (candidates,) + ) + .await? ); assert_eq!(jvm.get_field::(&never_reached, "keyCalls", "I").await?, 0); assert_eq!(jvm.get_field::(&never_reached, "valueCalls", "I").await?, 0); @@ -2663,18 +3565,38 @@ async fn test_coll_08_unmodifiable_entry_arrays_preserve_runtime_type_and_partia let key: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (value,)).await?.into(); let mapped: ClassInstanceRef = jvm.new_class("java/lang/Integer", "(I)V", (value * 10,)).await?.into(); let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, mapped)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, mapped), + ) .await?; } - let raw_entries: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - let raw_array: ClassInstanceRef> = jvm.invoke_virtual(&raw_entries, "toArray", "()[Ljava/lang/Object;", ()).await?; + let raw_entries: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let raw_array: ClassInstanceRef> = jvm + .invoke_virtual( + &raw_entries, + &raw_entries.class_definition().name(), + "toArray", + "()[Ljava/lang/Object;", + (), + ) + .await?; let raw_values = jvm.load_array::>(&raw_array, 0, 2).await?; let wrapped_map: ClassInstanceRef = jvm .invoke_static("java/util/Collections", "unmodifiableMap", "(Ljava/util/Map;)Ljava/util/Map;", (map,)) .await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&wrapped_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&wrapped_map, &wrapped_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; - let untyped: ClassInstanceRef> = jvm.invoke_virtual(&entries, "toArray", "()[Ljava/lang/Object;", ()).await?; + let untyped: ClassInstanceRef> = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; for entry in jvm.load_array::>(&untyped, 0, 2).await? { assert_eq!( entry.class_definition().name(), @@ -2682,7 +3604,13 @@ async fn test_coll_08_unmodifiable_entry_arrays_preserve_runtime_type_and_partia ); let null: ClassInstanceRef = None.into(); let result: Result> = jvm - .invoke_virtual(&entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (null,)) + .invoke_virtual( + &entry, + &entry.class_definition().name(), + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (null,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("untyped entry array must contain only unmodifiable entries"); @@ -2694,7 +3622,13 @@ async fn test_coll_08_unmodifiable_entry_arrays_preserve_runtime_type_and_partia jvm.store_array(&mut oversized, 2, [raw_values[0].clone(), raw_values[1].clone()]).await?; let oversized_identity = oversized.identity(); let reused: ClassInstanceRef> = jvm - .invoke_virtual(&entries, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (oversized,)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (oversized,), + ) .await?; assert_eq!(reused.identity(), oversized_identity); let reused_values = jvm.load_array::>(&reused, 0, 4).await?; @@ -2713,7 +3647,13 @@ async fn test_coll_08_unmodifiable_entry_arrays_preserve_runtime_type_and_partia let small: ClassInstanceRef> = jvm.instantiate_array("Ljava/util/Map$Entry;", 0).await?.into(); let grown: ClassInstanceRef> = jvm - .invoke_virtual(&entries, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (small,)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (small,), + ) .await?; assert_eq!(grown.class_definition().name(), "[Ljava/util/Map$Entry;"); assert_eq!(jvm.array_length(&grown).await?, 2); @@ -2727,7 +3667,13 @@ async fn test_coll_08_unmodifiable_entry_arrays_preserve_runtime_type_and_partia let mut concrete: ClassInstanceRef> = jvm.instantiate_array("Ljava/util/HashMap$Entry;", 2).await?.into(); jvm.store_array(&mut concrete, 0, [raw_values[0].clone(), raw_values[1].clone()]).await?; let result: Result>> = jvm - .invoke_virtual(&entries, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (concrete.clone(),)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (concrete.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("HashMap.Entry[] must reject wrapped entries"); @@ -2742,7 +3688,13 @@ async fn test_coll_08_unmodifiable_entry_arrays_preserve_runtime_type_and_partia jvm.store_array(&mut matrix, 0, [sentinel_row.clone(), sentinel_row.clone(), sentinel_row.clone()]) .await?; let result: Result>> = jvm - .invoke_virtual(&entries, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (matrix.clone(),)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (matrix.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Map.Entry[][] must reject scalar wrapped entries"); @@ -2766,6 +3718,7 @@ async fn test_coll_08_unmodifiable_sorted_ranges_remain_live_and_unmodifiable() let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value), @@ -2791,31 +3744,68 @@ async fn test_coll_08_unmodifiable_sorted_ranges_remain_live_and_unmodifiable() .await?; assert_ne!(sorted_map.identity(), nested_sorted_map.identity()); assert!( - jvm.invoke_virtual::<_, ClassInstanceRef>(&sorted_map, "comparator", "()Ljava/util/Comparator;", ()) - .await? - .is_null() + jvm.invoke_virtual::<_, ClassInstanceRef>( + &sorted_map, + &sorted_map.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + () + ) + .await? + .is_null() + ); + let first: ClassInstanceRef = jvm + .invoke_virtual(&sorted_map, &sorted_map.class_definition().name(), "firstKey", "()Ljava/lang/Object;", ()) + .await?; + let last: ClassInstanceRef = jvm + .invoke_virtual(&sorted_map, &sorted_map.class_definition().name(), "lastKey", "()Ljava/lang/Object;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "intValue", "()I", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&last, &last.class_definition().name(), "intValue", "()I", ()) + .await?, + 5 ); - let first: ClassInstanceRef = jvm.invoke_virtual(&sorted_map, "firstKey", "()Ljava/lang/Object;", ()).await?; - let last: ClassInstanceRef = jvm.invoke_virtual(&sorted_map, "lastKey", "()Ljava/lang/Object;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "intValue", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&last, "intValue", "()I", ()).await?, 5); let range: ClassInstanceRef = jvm .invoke_virtual( &sorted_map, + &sorted_map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (keys[0].clone(), keys[2].clone()), ) .await?; let nested_range: ClassInstanceRef = jvm - .invoke_virtual(&range, "headMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (keys[1].clone(),)) + .invoke_virtual( + &range, + &range.class_definition().name(), + "headMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (keys[1].clone(),), + ) .await?; let head_range: ClassInstanceRef = jvm - .invoke_virtual(&sorted_map, "headMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (keys[2].clone(),)) + .invoke_virtual( + &sorted_map, + &sorted_map.class_definition().name(), + "headMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (keys[2].clone(),), + ) .await?; let tail_range: ClassInstanceRef = jvm - .invoke_virtual(&sorted_map, "tailMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (keys[0].clone(),)) + .invoke_virtual( + &sorted_map, + &sorted_map.class_definition().name(), + "tailMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (keys[0].clone(),), + ) .await?; for wrapped_range in [&range, &nested_range, &head_range, &tail_range] { assert_eq!(wrapped_range.class_definition().name(), "java/util/Collections$UnmodifiableSortedMap"); @@ -2825,30 +3815,56 @@ async fn test_coll_08_unmodifiable_sorted_ranges_remain_live_and_unmodifiable() let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (inserted_key.clone(), inserted_value.clone()), ) .await?; assert!( - jvm.invoke_virtual::<_, bool>(&range, "containsKey", "(Ljava/lang/Object;)Z", (inserted_key.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &range, + &range.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (inserted_key.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&nested_range, "containsKey", "(Ljava/lang/Object;)Z", (inserted_key.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &nested_range, + &nested_range.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (inserted_key.clone(),), + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&head_range, "containsKey", "(Ljava/lang/Object;)Z", (inserted_key.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &head_range, + &head_range.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (inserted_key.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&tail_range, "containsKey", "(Ljava/lang/Object;)Z", (inserted_key.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &tail_range, + &tail_range.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (inserted_key.clone(),) + ) + .await? ); let put: Result> = jvm .invoke_virtual( &range, + &range.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (inserted_key.clone(), inserted_value), @@ -2861,7 +3877,9 @@ async fn test_coll_08_unmodifiable_sorted_ranges_remain_live_and_unmodifiable() let set: ClassInstanceRef = jvm.new_class("java/util/TreeSet", "()V", ()).await?.into(); for key in &keys { - let _: bool = jvm.invoke_virtual(&set, "add", "(Ljava/lang/Object;)Z", (key.clone(),)).await?; + let _: bool = jvm + .invoke_virtual(&set, &set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (key.clone(),)) + .await?; } let sorted_set: ClassInstanceRef = jvm .invoke_static( @@ -2881,17 +3899,36 @@ async fn test_coll_08_unmodifiable_sorted_ranges_remain_live_and_unmodifiable() .await?; assert_ne!(sorted_set.identity(), nested_sorted_set.identity()); assert!( - jvm.invoke_virtual::<_, ClassInstanceRef>(&sorted_set, "comparator", "()Ljava/util/Comparator;", ()) - .await? - .is_null() + jvm.invoke_virtual::<_, ClassInstanceRef>( + &sorted_set, + &sorted_set.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + () + ) + .await? + .is_null() + ); + let first: ClassInstanceRef = jvm + .invoke_virtual(&sorted_set, &sorted_set.class_definition().name(), "first", "()Ljava/lang/Object;", ()) + .await?; + let last: ClassInstanceRef = jvm + .invoke_virtual(&sorted_set, &sorted_set.class_definition().name(), "last", "()Ljava/lang/Object;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "intValue", "()I", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&last, &last.class_definition().name(), "intValue", "()I", ()) + .await?, + 5 ); - let first: ClassInstanceRef = jvm.invoke_virtual(&sorted_set, "first", "()Ljava/lang/Object;", ()).await?; - let last: ClassInstanceRef = jvm.invoke_virtual(&sorted_set, "last", "()Ljava/lang/Object;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "intValue", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&last, "intValue", "()I", ()).await?, 5); let set_range: ClassInstanceRef = jvm .invoke_virtual( &sorted_set, + &sorted_set.class_definition().name(), "subSet", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedSet;", (keys[0].clone(), keys[2].clone()), @@ -2900,38 +3937,91 @@ async fn test_coll_08_unmodifiable_sorted_ranges_remain_live_and_unmodifiable() let nested_set_range: ClassInstanceRef = jvm .invoke_virtual( &set_range, + &set_range.class_definition().name(), "tailSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (inserted_key.clone(),), ) .await?; let head_set_range: ClassInstanceRef = jvm - .invoke_virtual(&sorted_set, "headSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (keys[2].clone(),)) + .invoke_virtual( + &sorted_set, + &sorted_set.class_definition().name(), + "headSet", + "(Ljava/lang/Object;)Ljava/util/SortedSet;", + (keys[2].clone(),), + ) .await?; let tail_set_range: ClassInstanceRef = jvm - .invoke_virtual(&sorted_set, "tailSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (keys[0].clone(),)) + .invoke_virtual( + &sorted_set, + &sorted_set.class_definition().name(), + "tailSet", + "(Ljava/lang/Object;)Ljava/util/SortedSet;", + (keys[0].clone(),), + ) .await?; for wrapped_range in [&set_range, &nested_set_range, &head_set_range, &tail_set_range] { assert_eq!(wrapped_range.class_definition().name(), "java/util/Collections$UnmodifiableSortedSet"); } - let _: bool = jvm.invoke_virtual(&set, "add", "(Ljava/lang/Object;)Z", (inserted_key.clone(),)).await?; + let _: bool = jvm + .invoke_virtual( + &set, + &set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (inserted_key.clone(),), + ) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&set_range, "contains", "(Ljava/lang/Object;)Z", (inserted_key.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &set_range, + &set_range.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (inserted_key.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&nested_set_range, "contains", "(Ljava/lang/Object;)Z", (inserted_key.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &nested_set_range, + &nested_set_range.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (inserted_key.clone(),), + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&head_set_range, "contains", "(Ljava/lang/Object;)Z", (inserted_key.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &head_set_range, + &head_set_range.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (inserted_key.clone(),), + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&tail_set_range, "contains", "(Ljava/lang/Object;)Z", (inserted_key.clone(),),) - .await? + jvm.invoke_virtual::<_, bool>( + &tail_set_range, + &tail_set_range.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (inserted_key.clone(),), + ) + .await? ); - let add: Result = jvm.invoke_virtual(&set_range, "add", "(Ljava/lang/Object;)Z", (inserted_key,)).await; + let add: Result = jvm + .invoke_virtual( + &set_range, + &set_range.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (inserted_key,), + ) + .await; let Err(JavaError::JavaException(exception)) = add else { panic!("sorted set range must remain unmodifiable"); }; @@ -2958,7 +4048,13 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun for key in [high.clone(), middle.clone(), low.clone(), null.clone()] { let value = JavaLangString::from_rust_string(&jvm, "value").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } let sorted_map: ClassInstanceRef = jvm @@ -2969,34 +4065,66 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun (map.clone(),), ) .await?; - let returned_comparator: ClassInstanceRef = jvm.invoke_virtual(&sorted_map, "comparator", "()Ljava/util/Comparator;", ()).await?; + let returned_comparator: ClassInstanceRef = jvm + .invoke_virtual( + &sorted_map, + &sorted_map.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + (), + ) + .await?; assert_eq!(returned_comparator.identity(), comparator.identity()); assert!( - jvm.invoke_virtual::<_, bool>(&sorted_map, "containsKey", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &sorted_map, + &sorted_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); - let first_key: ClassInstanceRef = jvm.invoke_virtual(&sorted_map, "firstKey", "()Ljava/lang/Object;", ()).await?; - let last_key: ClassInstanceRef = jvm.invoke_virtual(&sorted_map, "lastKey", "()Ljava/lang/Object;", ()).await?; + let first_key: ClassInstanceRef = jvm + .invoke_virtual(&sorted_map, &sorted_map.class_definition().name(), "firstKey", "()Ljava/lang/Object;", ()) + .await?; + let last_key: ClassInstanceRef = jvm + .invoke_virtual(&sorted_map, &sorted_map.class_definition().name(), "lastKey", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(first_key.identity(), high.identity()); assert!(last_key.is_null()); let map_range: ClassInstanceRef = jvm .invoke_virtual( &sorted_map, + &sorted_map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (high.clone(), null.clone()), ) .await?; let map_head: ClassInstanceRef = jvm - .invoke_virtual(&sorted_map, "headMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (null.clone(),)) + .invoke_virtual( + &sorted_map, + &sorted_map.class_definition().name(), + "headMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (null.clone(),), + ) .await?; let map_tail: ClassInstanceRef = jvm - .invoke_virtual(&sorted_map, "tailMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (null.clone(),)) + .invoke_virtual( + &sorted_map, + &sorted_map.class_definition().name(), + "tailMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (null.clone(),), + ) .await?; let nested_map: ClassInstanceRef = jvm .invoke_virtual( &map_range, + &map_range.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (middle.clone(), low.clone()), @@ -3005,6 +4133,7 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun let equal_map: ClassInstanceRef = jvm .invoke_virtual( &map_range, + &map_range.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (middle.clone(), middle.clone()), @@ -3012,22 +4141,41 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun .await?; for range in [&map_range, &map_head, &map_tail, &nested_map, &equal_map] { assert_eq!(range.class_definition().name(), "java/util/Collections$UnmodifiableSortedMap"); - let range_comparator: ClassInstanceRef = jvm.invoke_virtual(range, "comparator", "()Ljava/util/Comparator;", ()).await?; + let range_comparator: ClassInstanceRef = jvm + .invoke_virtual(range, &range.class_definition().name(), "comparator", "()Ljava/util/Comparator;", ()) + .await?; assert_eq!(range_comparator.identity(), comparator.identity()); } - assert_eq!(jvm.invoke_virtual::<_, i32>(&equal_map, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&equal_map, &equal_map.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); assert!( - !jvm.invoke_virtual::<_, bool>(&map_head, "containsKey", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &map_head, + &map_head.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&map_tail, "containsKey", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &map_tail, + &map_tail.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); let result: Result> = jvm .invoke_virtual( &sorted_map, + &sorted_map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (low.clone(), high.clone()), @@ -3038,7 +4186,13 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/IllegalArgumentException")); let result: Result> = jvm - .invoke_virtual(&map_range, "tailMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (outside.clone(),)) + .invoke_virtual( + &map_range, + &map_range.class_definition().name(), + "tailMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (outside.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("nested map range must reject an endpoint outside its lower boundary"); @@ -3049,19 +4203,32 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (live_key.clone(), live_value.clone()), ) .await?; assert!( - jvm.invoke_virtual::<_, bool>(&map_range, "containsKey", "(Ljava/lang/Object;)Z", (live_key.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &map_range, + &map_range.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (live_key.clone(),) + ) + .await? ); jvm.put_field(&mut comparator.clone(), "fail", "Z", true).await?; let result: Result> = jvm - .invoke_virtual(&map_range, "headMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (middle.clone(),)) + .invoke_virtual( + &map_range, + &map_range.class_definition().name(), + "headMap", + "(Ljava/lang/Object;)Ljava/util/SortedMap;", + (middle.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("range factory must propagate the backing comparator exception"); @@ -3070,6 +4237,7 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun let result: Result> = jvm .invoke_virtual( &map_range, + &map_range.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (outside.clone(), live_value), @@ -3086,7 +4254,9 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun .await? .into(); for key in [high.clone(), middle.clone(), low.clone(), null.clone()] { - let _: bool = jvm.invoke_virtual(&set, "add", "(Ljava/lang/Object;)Z", (key,)).await?; + let _: bool = jvm + .invoke_virtual(&set, &set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (key,)) + .await?; } let sorted_set: ClassInstanceRef = jvm .invoke_static( @@ -3096,34 +4266,66 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun (set.clone(),), ) .await?; - let returned_comparator: ClassInstanceRef = jvm.invoke_virtual(&sorted_set, "comparator", "()Ljava/util/Comparator;", ()).await?; + let returned_comparator: ClassInstanceRef = jvm + .invoke_virtual( + &sorted_set, + &sorted_set.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + (), + ) + .await?; assert_eq!(returned_comparator.identity(), comparator.identity()); assert!( - jvm.invoke_virtual::<_, bool>(&sorted_set, "contains", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &sorted_set, + &sorted_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); - let first: ClassInstanceRef = jvm.invoke_virtual(&sorted_set, "first", "()Ljava/lang/Object;", ()).await?; - let last: ClassInstanceRef = jvm.invoke_virtual(&sorted_set, "last", "()Ljava/lang/Object;", ()).await?; + let first: ClassInstanceRef = jvm + .invoke_virtual(&sorted_set, &sorted_set.class_definition().name(), "first", "()Ljava/lang/Object;", ()) + .await?; + let last: ClassInstanceRef = jvm + .invoke_virtual(&sorted_set, &sorted_set.class_definition().name(), "last", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(first.identity(), high.identity()); assert!(last.is_null()); let set_range: ClassInstanceRef = jvm .invoke_virtual( &sorted_set, + &sorted_set.class_definition().name(), "subSet", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedSet;", (high.clone(), null.clone()), ) .await?; let set_head: ClassInstanceRef = jvm - .invoke_virtual(&sorted_set, "headSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (null.clone(),)) + .invoke_virtual( + &sorted_set, + &sorted_set.class_definition().name(), + "headSet", + "(Ljava/lang/Object;)Ljava/util/SortedSet;", + (null.clone(),), + ) .await?; let set_tail: ClassInstanceRef = jvm - .invoke_virtual(&sorted_set, "tailSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (null.clone(),)) + .invoke_virtual( + &sorted_set, + &sorted_set.class_definition().name(), + "tailSet", + "(Ljava/lang/Object;)Ljava/util/SortedSet;", + (null.clone(),), + ) .await?; let nested_set: ClassInstanceRef = jvm .invoke_virtual( &set_range, + &set_range.class_definition().name(), "subSet", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedSet;", (middle.clone(), low.clone()), @@ -3132,6 +4334,7 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun let equal_set: ClassInstanceRef = jvm .invoke_virtual( &set_range, + &set_range.class_definition().name(), "subSet", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedSet;", (middle.clone(), middle.clone()), @@ -3139,22 +4342,41 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun .await?; for range in [&set_range, &set_head, &set_tail, &nested_set, &equal_set] { assert_eq!(range.class_definition().name(), "java/util/Collections$UnmodifiableSortedSet"); - let range_comparator: ClassInstanceRef = jvm.invoke_virtual(range, "comparator", "()Ljava/util/Comparator;", ()).await?; + let range_comparator: ClassInstanceRef = jvm + .invoke_virtual(range, &range.class_definition().name(), "comparator", "()Ljava/util/Comparator;", ()) + .await?; assert_eq!(range_comparator.identity(), comparator.identity()); } - assert_eq!(jvm.invoke_virtual::<_, i32>(&equal_set, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&equal_set, &equal_set.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); assert!( - !jvm.invoke_virtual::<_, bool>(&set_head, "contains", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &set_head, + &set_head.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&set_tail, "contains", "(Ljava/lang/Object;)Z", (null.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &set_tail, + &set_tail.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null.clone(),) + ) + .await? ); let result: Result> = jvm .invoke_virtual( &sorted_set, + &sorted_set.class_definition().name(), "subSet", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedSet;", (low, high), @@ -3165,28 +4387,56 @@ async fn test_coll_08_unmodifiable_sorted_ranges_preserve_custom_comparator_boun }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/IllegalArgumentException")); let result: Result> = jvm - .invoke_virtual(&set_range, "tailSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (outside.clone(),)) + .invoke_virtual( + &set_range, + &set_range.class_definition().name(), + "tailSet", + "(Ljava/lang/Object;)Ljava/util/SortedSet;", + (outside.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("nested set range must reject an endpoint outside its lower boundary"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/IllegalArgumentException")); - let _: bool = jvm.invoke_virtual(&set, "add", "(Ljava/lang/Object;)Z", (live_key.clone(),)).await?; + let _: bool = jvm + .invoke_virtual(&set, &set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (live_key.clone(),)) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&set_range, "contains", "(Ljava/lang/Object;)Z", (live_key,)) - .await? + jvm.invoke_virtual::<_, bool>( + &set_range, + &set_range.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (live_key,) + ) + .await? ); jvm.put_field(&mut comparator.clone(), "fail", "Z", true).await?; let result: Result> = jvm - .invoke_virtual(&set_range, "headSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (middle,)) + .invoke_virtual( + &set_range, + &set_range.class_definition().name(), + "headSet", + "(Ljava/lang/Object;)Ljava/util/SortedSet;", + (middle,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("set range factory must propagate the backing comparator exception"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/IllegalStateException")); - let result: Result = jvm.invoke_virtual(&set_range, "add", "(Ljava/lang/Object;)Z", (outside,)).await; + let result: Result = jvm + .invoke_virtual( + &set_range, + &set_range.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (outside,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("unmodifiable set mutation must throw before comparator range validation"); }; diff --git a/java_runtime/tests/classes/java/util/test_date.rs b/java_runtime/tests/classes/java/util/test_date.rs index 6a253736..e274f4a4 100644 --- a/java_runtime/tests/classes/java/util/test_date.rs +++ b/java_runtime/tests/classes/java/util/test_date.rs @@ -10,13 +10,28 @@ async fn test_date_cldc11_value_contract() -> Result<()> { let same = jvm.new_class("java/util/Date", "(J)V", (0i64,)).await?; let later = jvm.new_class("java/util/Date", "(J)V", (1i64,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&epoch, "equals", "(Ljava/lang/Object;)Z", (same,)).await?); - assert!(!jvm.invoke_virtual::<_, bool>(&epoch, "equals", "(Ljava/lang/Object;)Z", (later,)).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&epoch, &epoch.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (same,)) + .await? + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&epoch, &epoch.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (later,)) + .await? + ); let null: ClassInstanceRef = None.into(); - assert!(!jvm.invoke_virtual::<_, bool>(&epoch, "equals", "(Ljava/lang/Object;)Z", (null,)).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&epoch, "hashCode", "()I", ()).await?, 0); + assert!( + !jvm.invoke_virtual::<_, bool>(&epoch, &epoch.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (null,)) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&epoch, &epoch.class_definition().name(), "hashCode", "()I", ()) + .await?, + 0 + ); - let text: ClassInstanceRef = jvm.invoke_virtual(&epoch, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&epoch, &epoch.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "Thu Jan 01 00:00:00 GMT 1970"); Ok(()) @@ -30,36 +45,78 @@ async fn test_date_01_compare_to_typed_and_object_contract() -> Result<()> { let later = jvm.new_class("java/util/Date", "(J)V", (20i64,)).await?; assert_eq!( - jvm.invoke_virtual::<_, i32>(&earlier, "compareTo", "(Ljava/util/Date;)I", (later.clone(),)) - .await?, + jvm.invoke_virtual::<_, i32>( + &earlier, + &earlier.class_definition().name(), + "compareTo", + "(Ljava/util/Date;)I", + (later.clone(),) + ) + .await?, -1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&later, "compareTo", "(Ljava/util/Date;)I", (earlier.clone(),)) - .await?, + jvm.invoke_virtual::<_, i32>( + &later, + &later.class_definition().name(), + "compareTo", + "(Ljava/util/Date;)I", + (earlier.clone(),) + ) + .await?, 1 ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&earlier, "compareTo", "(Ljava/lang/Object;)I", (same,)) - .await?, + jvm.invoke_virtual::<_, i32>( + &earlier, + &earlier.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (same,) + ) + .await?, 0 ); let null: ClassInstanceRef = None.into(); - let result: Result = jvm.invoke_virtual(&earlier, "compareTo", "(Ljava/util/Date;)I", (null.clone(),)).await; + let result: Result = jvm + .invoke_virtual( + &earlier, + &earlier.class_definition().name(), + "compareTo", + "(Ljava/util/Date;)I", + (null.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Date.compareTo(Date) must reject null"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let result: Result = jvm.invoke_virtual(&earlier, "compareTo", "(Ljava/lang/Object;)I", (null,)).await; + let result: Result = jvm + .invoke_virtual( + &earlier, + &earlier.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (null,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Date.compareTo(Object) must reject null"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); let object = jvm.new_class("java/lang/Object", "()V", ()).await?; - let result: Result = jvm.invoke_virtual(&earlier, "compareTo", "(Ljava/lang/Object;)I", (object,)).await; + let result: Result = jvm + .invoke_virtual( + &earlier, + &earlier.class_definition().name(), + "compareTo", + "(Ljava/lang/Object;)I", + (object,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Date.compareTo(Object) must reject non-Date values"); }; @@ -75,19 +132,38 @@ async fn test_date_02_before_after_and_null_contract() -> Result<()> { let later = jvm.new_class("java/util/Date", "(J)V", (20i64,)).await?; assert!( - jvm.invoke_virtual::<_, bool>(&earlier, "before", "(Ljava/util/Date;)Z", (later.clone(),)) + jvm.invoke_virtual::<_, bool>( + &earlier, + &earlier.class_definition().name(), + "before", + "(Ljava/util/Date;)Z", + (later.clone(),) + ) + .await? + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&earlier, &earlier.class_definition().name(), "after", "(Ljava/util/Date;)Z", (later,)) .await? ); - assert!(!jvm.invoke_virtual::<_, bool>(&earlier, "after", "(Ljava/util/Date;)Z", (later,)).await?); let null: ClassInstanceRef = None.into(); - let result: Result = jvm.invoke_virtual(&earlier, "before", "(Ljava/util/Date;)Z", (null.clone(),)).await; + let result: Result = jvm + .invoke_virtual( + &earlier, + &earlier.class_definition().name(), + "before", + "(Ljava/util/Date;)Z", + (null.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Date.before must reject null"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - let result: Result = jvm.invoke_virtual(&earlier, "after", "(Ljava/util/Date;)Z", (null,)).await; + let result: Result = jvm + .invoke_virtual(&earlier, &earlier.class_definition().name(), "after", "(Ljava/util/Date;)Z", (null,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Date.after must reject null"); }; diff --git a/java_runtime/tests/classes/java/util/test_formatter.rs b/java_runtime/tests/classes/java/util/test_formatter.rs index a2a2f419..2ef74d53 100644 --- a/java_runtime/tests/classes/java/util/test_formatter.rs +++ b/java_runtime/tests/classes/java/util/test_formatter.rs @@ -513,12 +513,16 @@ async fn format_exception_state_messages_and_null_contracts_match_java_5() -> Re ] { let value = JavaLangString::from_rust_string(&jvm, value).await?; let exception = jvm.new_class(class, "(Ljava/lang/String;)V", (value.clone(),)).await?; - let stored: ClassInstanceRef = jvm.invoke_virtual(&exception, getter, "()Ljava/lang/String;", ()).await?; + let stored: ClassInstanceRef = jvm + .invoke_virtual(&exception, &exception.class_definition().name(), getter, "()Ljava/lang/String;", ()) + .await?; assert_eq!( JavaLangString::to_rust_string(&jvm, &stored).await?, JavaLangString::to_rust_string(&jvm, &value).await? ); - let message: ClassInstanceRef = jvm.invoke_virtual(&exception, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual(&exception, &exception.class_definition().name(), "getMessage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, expected_message); let null = ClassInstanceRef::::new(None); @@ -537,10 +541,18 @@ async fn format_exception_state_messages_and_null_contracts_match_java_5() -> Re (flags, 'b' as u16), ) .await?; - let stored_flags: ClassInstanceRef = jvm.invoke_virtual(&mismatch, "getFlags", "()Ljava/lang/String;", ()).await?; + let stored_flags: ClassInstanceRef = jvm + .invoke_virtual(&mismatch, &mismatch.class_definition().name(), "getFlags", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &stored_flags).await?, "#"); - assert_eq!(jvm.invoke_virtual::<_, u16>(&mismatch, "getConversion", "()C", ()).await?, 'b' as u16); - let message: ClassInstanceRef = jvm.invoke_virtual(&mismatch, "getMessage", "()Ljava/lang/String;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, u16>(&mismatch, &mismatch.class_definition().name(), "getConversion", "()C", ()) + .await?, + 'b' as u16 + ); + let message: ClassInstanceRef = jvm + .invoke_virtual(&mismatch, &mismatch.class_definition().name(), "getMessage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, "Conversion = b, Flags = #"); let null_flags = ClassInstanceRef::::new(None); let result = jvm @@ -556,8 +568,20 @@ async fn format_exception_state_messages_and_null_contracts_match_java_5() -> Re assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); let code_point = jvm.new_class("java/util/IllegalFormatCodePointException", "(I)V", (-1,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&code_point, "getCodePoint", "()I", ()).await?, -1); - let message: ClassInstanceRef = jvm.invoke_virtual(&code_point, "getMessage", "()Ljava/lang/String;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&code_point, &code_point.class_definition().name(), "getCodePoint", "()I", ()) + .await?, + -1 + ); + let message: ClassInstanceRef = jvm + .invoke_virtual( + &code_point, + &code_point.class_definition().name(), + "getMessage", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, "Code point = 0xffffffff"); let string_class: ClassInstanceRef = jvm.resolve_class("java/lang/String").await?.java_class().into(); @@ -568,10 +592,30 @@ async fn format_exception_state_messages_and_null_contracts_match_java_5() -> Re ('d' as u16, string_class.clone()), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, u16>(&conversion, "getConversion", "()C", ()).await?, 'd' as u16); - let stored_class: ClassInstanceRef = jvm.invoke_virtual(&conversion, "getArgumentClass", "()Ljava/lang/Class;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, u16>(&conversion, &conversion.class_definition().name(), "getConversion", "()C", ()) + .await?, + 'd' as u16 + ); + let stored_class: ClassInstanceRef = jvm + .invoke_virtual( + &conversion, + &conversion.class_definition().name(), + "getArgumentClass", + "()Ljava/lang/Class;", + (), + ) + .await?; assert_eq!(stored_class.identity(), string_class.identity()); - let message: ClassInstanceRef = jvm.invoke_virtual(&conversion, "getMessage", "()Ljava/lang/String;", ()).await?; + let message: ClassInstanceRef = jvm + .invoke_virtual( + &conversion, + &conversion.class_definition().name(), + "getMessage", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, "d != java.lang.String"); let null_class = ClassInstanceRef::::new(None); let result = jvm @@ -591,8 +635,14 @@ async fn format_exception_state_messages_and_null_contracts_match_java_5() -> Re ("java/util/IllegalFormatWidthException", "getWidth", -3), ] { let exception = jvm.new_class(class, "(I)V", (value,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&exception, getter, "()I", ()).await?, value); - let message: ClassInstanceRef = jvm.invoke_virtual(&exception, "getMessage", "()Ljava/lang/String;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&exception, &exception.class_definition().name(), getter, "()I", ()) + .await?, + value + ); + let message: ClassInstanceRef = jvm + .invoke_virtual(&exception, &exception.class_definition().name(), "getMessage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &message).await?, value.to_string()); } @@ -609,9 +659,21 @@ async fn formatter_big_decimal_layout_form_has_java_5_enum_identity_and_order() "Ljava/util/Formatter$BigDecimalLayoutForm;", ) .await?; - let name = jvm.invoke_virtual(&scientific, "name", "()Ljava/lang/String;", ()).await?; + let name = jvm + .invoke_virtual( + &scientific, + "java/util/Formatter$BigDecimalLayoutForm", + "name", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &name).await?, "SCIENTIFIC"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&scientific, "ordinal", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&scientific, "java/util/Formatter$BigDecimalLayoutForm", "ordinal", "()I", ()) + .await?, + 0 + ); let values: ClassInstanceRef> = jvm .invoke_static( @@ -631,7 +693,11 @@ async fn formatter_big_decimal_layout_form_has_java_5_enum_identity_and_order() (requested,), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&decimal, "ordinal", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&decimal, "java/util/Formatter$BigDecimalLayoutForm", "ordinal", "()I", ()) + .await?, + 1 + ); Ok(()) } @@ -655,12 +721,15 @@ async fn formatter_formats_common_java_5_conversions() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - let result = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "ok 0007 12.50 % \n"); Ok(()) @@ -679,12 +748,15 @@ async fn formatter_tracks_explicit_previous_and_ordinary_arguments_independently let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - let result = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "two|26|1a|26"); let formatter = jvm.new_class("java/util/Formatter", "()V", ()).await?; @@ -693,12 +765,15 @@ async fn formatter_tracks_explicit_previous_and_ordinary_arguments_independently let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - let result = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "null|false"); let format = JavaLangString::from_rust_string(&jvm, "|%+x").await?; @@ -706,12 +781,15 @@ async fn formatter_tracks_explicit_previous_and_ordinary_arguments_independently let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - let result = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "null|false|null"); Ok(()) @@ -731,12 +809,15 @@ async fn formatter_uppercase_preserves_unpaired_utf16_surrogates() -> Result<()> let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - let result = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!( JavaLangString::to_utf16(&jvm, &result).await?, vec!['A' as u16, 0xd800, 'B' as u16, '|' as u16, 0xd800] @@ -762,13 +843,16 @@ async fn print_stream_and_print_writer_use_formatter_for_varargs_output() -> Res let returned: ClassInstanceRef = jvm .invoke_virtual( &stream, + &stream.class_definition().name(), "printf", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;", (format.clone(), arguments.clone()), ) .await?; assert_eq!(returned.identity(), stream.identity()); - let stream_text = jvm.invoke_virtual(&bytes, "toString", "()Ljava/lang/String;", ()).await?; + let stream_text = jvm + .invoke_virtual(&bytes, &bytes.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &stream_text).await?, "n=007"); let string_writer = jvm.new_class("java/io/StringWriter", "()V", ()).await?; @@ -778,13 +862,22 @@ async fn print_stream_and_print_writer_use_formatter_for_varargs_output() -> Res let returned: ClassInstanceRef = jvm .invoke_virtual( &writer, + &writer.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;", (format, arguments), ) .await?; assert_eq!(returned.identity(), writer.identity()); - let writer_text = jvm.invoke_virtual(&string_writer, "toString", "()Ljava/lang/String;", ()).await?; + let writer_text = jvm + .invoke_virtual( + &string_writer, + &string_writer.class_definition().name(), + "toString", + "()Ljava/lang/String;", + (), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &writer_text).await?, "n=007"); Ok(()) @@ -841,12 +934,16 @@ async fn formatter_and_print_file_constructors_enforce_java_5_null_contracts() - let formatter = jvm .new_class("java/util/Formatter", "(Ljava/lang/Appendable;)V", (null_appendable,)) .await?; - let out: ClassInstanceRef = jvm.invoke_virtual(&formatter, "out", "()Ljava/lang/Appendable;", ()).await?; + let out: ClassInstanceRef = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "out", "()Ljava/lang/Appendable;", ()) + .await?; assert!(jvm.is_instance(&**out, "java/lang/StringBuilder")); let null_locale = ClassInstanceRef::::new(None); let formatter = jvm.new_class("java/util/Formatter", "(Ljava/util/Locale;)V", (null_locale,)).await?; - let locale: ClassInstanceRef = jvm.invoke_virtual(&formatter, "locale", "()Ljava/util/Locale;", ()).await?; + let locale: ClassInstanceRef = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "locale", "()Ljava/util/Locale;", ()) + .await?; assert!(locale.is_null()); let null_path = ClassInstanceRef::::new(None); @@ -944,12 +1041,15 @@ async fn formatter_handles_numeric_radix_grouping_and_uppercase_conversions() -> let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - let result = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!( JavaLangString::to_rust_string(&jvm, &result).await?, "(1,234)|ffffffff|37777777777|1.23e+03|1234|A|TRUE" @@ -985,12 +1085,15 @@ async fn formatter_matches_java_5_radix_and_non_finite_number_rules() -> Result< let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - let result = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "00|0x00f|1.e+00|NaN| Infinity"); for (format, expected) in [ @@ -1005,6 +1108,7 @@ async fn formatter_matches_java_5_radix_and_non_finite_number_rules() -> Result< let result: Result> = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), @@ -1052,12 +1156,15 @@ async fn formatter_rounds_fixed_scientific_and_general_values_like_java_5() -> R let _: ClassInstanceRef = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), ) .await?; - let result = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let result = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!( JavaLangString::to_rust_string(&jvm, &result).await?, "2.68|10.000|1|1.00e+01|0.00000|9.99999e-05|1.00000e-05|1.00000e+06|1.000e+04|10.00|-0.00000|1.20000|4.90e-324|4.90e-324|1.80e+308|2|1.01" @@ -1090,6 +1197,7 @@ async fn formatter_throws_java_5_format_exceptions_and_rejects_use_after_close() let result: Result> = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), @@ -1102,8 +1210,12 @@ async fn formatter_throws_java_5_format_exceptions_and_rejects_use_after_close() } let formatter = jvm.new_class("java/util/Formatter", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&formatter, "close", "()V", ()).await?; - let result: Result> = jvm.invoke_virtual(&formatter, "out", "()Ljava/lang/Appendable;", ()).await; + let _: () = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "close", "()V", ()) + .await?; + let result: Result> = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "out", "()Ljava/lang/Appendable;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("FormatterClosedException must be thrown"); }; @@ -1124,6 +1236,7 @@ async fn formatter_validates_all_syntax_before_writing_but_preserves_runtime_par let result: Result> = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), @@ -1133,7 +1246,9 @@ async fn formatter_validates_all_syntax_before_writing_but_preserves_runtime_par panic!("the trailing unknown conversion must fail"); }; assert!(jvm.is_instance(&*exception, "java/util/UnknownFormatConversionException")); - let text = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let text = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, ""); let formatter = jvm.new_class("java/util/Formatter", "()V", ()).await?; @@ -1144,6 +1259,7 @@ async fn formatter_validates_all_syntax_before_writing_but_preserves_runtime_par let result: Result> = jvm .invoke_virtual( &formatter, + &formatter.class_definition().name(), "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/util/Formatter;", (format, arguments), @@ -1153,7 +1269,9 @@ async fn formatter_validates_all_syntax_before_writing_but_preserves_runtime_par panic!("the incompatible runtime argument must fail"); }; assert!(jvm.is_instance(&*exception, "java/util/IllegalFormatConversionException")); - let text = jvm.invoke_virtual(&formatter, "toString", "()Ljava/lang/String;", ()).await?; + let text = jvm + .invoke_virtual(&formatter, &formatter.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "before "); Ok(()) diff --git a/java_runtime/tests/classes/java/util/test_gregorian_calendar.rs b/java_runtime/tests/classes/java/util/test_gregorian_calendar.rs index 2daa58d3..409b502f 100644 --- a/java_runtime/tests/classes/java/util/test_gregorian_calendar.rs +++ b/java_runtime/tests/classes/java/util/test_gregorian_calendar.rs @@ -13,42 +13,68 @@ async fn test_gregorian_calendar() -> Result<()> { .await?; let date = jvm.new_class("java/util/Date", "(J)V", (timestamp,)).await?; - let _: () = jvm.invoke_virtual(&calendar, "setTime", "(Ljava/util/Date;)V", (date,)).await?; - let year: i32 = jvm.invoke_virtual(&calendar, "get", "(I)I", (1,)).await?; + let _: () = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "setTime", "(Ljava/util/Date;)V", (date,)) + .await?; + let year: i32 = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "get", "(I)I", (1,)) + .await?; assert_eq!(1970, year); - let month: i32 = jvm.invoke_virtual(&calendar, "get", "(I)I", (2,)).await?; + let month: i32 = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "get", "(I)I", (2,)) + .await?; assert_eq!(0, month); - let day: i32 = jvm.invoke_virtual(&calendar, "get", "(I)I", (5,)).await?; + let day: i32 = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "get", "(I)I", (5,)) + .await?; assert_eq!(1, day); let timestamp = 737521516000i64; let date = jvm.new_class("java/util/Date", "(J)V", (timestamp,)).await?; - let _: () = jvm.invoke_virtual(&calendar, "setTime", "(Ljava/util/Date;)V", (date,)).await?; + let _: () = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "setTime", "(Ljava/util/Date;)V", (date,)) + .await?; - let year: i32 = jvm.invoke_virtual(&calendar, "get", "(I)I", (1,)).await?; + let year: i32 = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "get", "(I)I", (1,)) + .await?; assert_eq!(1993, year); - let month: i32 = jvm.invoke_virtual(&calendar, "get", "(I)I", (2,)).await?; + let month: i32 = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "get", "(I)I", (2,)) + .await?; assert_eq!(4, month); - let day: i32 = jvm.invoke_virtual(&calendar, "get", "(I)I", (5,)).await?; + let day: i32 = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "get", "(I)I", (5,)) + .await?; assert_eq!(16, day); - let hour: i32 = jvm.invoke_virtual(&calendar, "get", "(I)I", (11,)).await?; + let hour: i32 = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "get", "(I)I", (11,)) + .await?; assert_eq!(3, hour); - let minute: i32 = jvm.invoke_virtual(&calendar, "get", "(I)I", (12,)).await?; + let minute: i32 = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "get", "(I)I", (12,)) + .await?; assert_eq!(5, minute); - let second: i32 = jvm.invoke_virtual(&calendar, "get", "(I)I", (13,)).await?; + let second: i32 = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "get", "(I)I", (13,)) + .await?; assert_eq!(16, second); - let _: () = jvm.invoke_virtual(&calendar, "set", "(II)V", (1, 1999)).await?; - let date = jvm.invoke_virtual(&calendar, "getTime", "()Ljava/util/Date;", ()).await?; - let timestamp: i64 = jvm.invoke_virtual(&date, "getTime", "()J", ()).await?; + let _: () = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "set", "(II)V", (1, 1999)) + .await?; + let date = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "getTime", "()Ljava/util/Date;", ()) + .await?; + let timestamp: i64 = jvm.invoke_virtual(&date, &date.class_definition().name(), "getTime", "()J", ()).await?; assert_eq!(926823916000, timestamp); Ok(()) @@ -64,30 +90,66 @@ async fn test_calendar_cldc11_time_and_comparison_api() -> Result<()> { .invoke_static("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;", ()) .await?; - let _: () = jvm.invoke_virtual(&first, "setTimeInMillis", "(J)V", (1000i64,)).await?; - let _: () = jvm.invoke_virtual(&second, "setTimeInMillis", "(J)V", (2000i64,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&first, "getTimeInMillis", "()J", ()).await?, 1000); + let _: () = jvm + .invoke_virtual(&first, &first.class_definition().name(), "setTimeInMillis", "(J)V", (1000i64,)) + .await?; + let _: () = jvm + .invoke_virtual(&second, &second.class_definition().name(), "setTimeInMillis", "(J)V", (2000i64,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i64>(&first, &first.class_definition().name(), "getTimeInMillis", "()J", ()) + .await?, + 1000 + ); assert!( - jvm.invoke_virtual::<_, bool>(&first, "before", "(Ljava/lang/Object;)Z", (second.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &first, + &first.class_definition().name(), + "before", + "(Ljava/lang/Object;)Z", + (second.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&second, "after", "(Ljava/lang/Object;)Z", (first.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &second, + &second.class_definition().name(), + "after", + "(Ljava/lang/Object;)Z", + (first.clone(),) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&first, "equals", "(Ljava/lang/Object;)Z", (second.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &first, + &first.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (second.clone(),) + ) + .await? ); - let _: () = jvm.invoke_virtual(&second, "setTimeInMillis", "(J)V", (1000i64,)).await?; + let _: () = jvm + .invoke_virtual(&second, &second.class_definition().name(), "setTimeInMillis", "(J)V", (1000i64,)) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&first, "equals", "(Ljava/lang/Object;)Z", (second.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &first, + &first.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (second.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&first, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&second, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&second, &second.class_definition().name(), "hashCode", "()I", ()) + .await? ); let id = JavaLangString::from_rust_string(&jvm, "JST").await?; @@ -97,10 +159,28 @@ async fn test_calendar_cldc11_time_and_comparison_api() -> Result<()> { let calendar: ClassInstanceRef = jvm .invoke_static("java/util/Calendar", "getInstance", "(Ljava/util/TimeZone;)Ljava/util/Calendar;", (zone,)) .await?; - let _: () = jvm.invoke_virtual(&calendar, "setTimeInMillis", "(J)V", (0i64,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&calendar, "get", "(I)I", (11,)).await?, 9); - let zone: ClassInstanceRef = jvm.invoke_virtual(&calendar, "getTimeZone", "()Ljava/util/TimeZone;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&zone, "getRawOffset", "()I", ()).await?, 9 * 60 * 60 * 1000); + let _: () = jvm + .invoke_virtual(&calendar, &calendar.class_definition().name(), "setTimeInMillis", "(J)V", (0i64,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&calendar, &calendar.class_definition().name(), "get", "(I)I", (11,)) + .await?, + 9 + ); + let zone: ClassInstanceRef = jvm + .invoke_virtual( + &calendar, + &calendar.class_definition().name(), + "getTimeZone", + "()Ljava/util/TimeZone;", + (), + ) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&zone, &zone.class_definition().name(), "getRawOffset", "()I", ()) + .await?, + 9 * 60 * 60 * 1000 + ); Ok(()) } diff --git a/java_runtime/tests/classes/java/util/test_hash_map.rs b/java_runtime/tests/classes/java/util/test_hash_map.rs index 80ea4b52..e5b502b5 100644 --- a/java_runtime/tests/classes/java/util/test_hash_map.rs +++ b/java_runtime/tests/classes/java/util/test_hash_map.rs @@ -197,12 +197,16 @@ async fn object_array_to_optional_strings(jvm: &Jvm, array: &ClassInstanceRef) -> Result>> { let mut values = Vec::new(); loop { - let has_next: bool = jvm.invoke_virtual(iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; if !has_next { break; } - let value: ClassInstanceRef = jvm.invoke_virtual(iterator, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; values.push(object_to_optional_string(jvm, &value).await?); } @@ -212,8 +216,12 @@ async fn iterator_to_optional_strings(jvm: &Jvm, iterator: &ClassInstanceRef) -> Result<(Option, Option)> { assert!(jvm.is_instance(&***entry, "java/util/Map$Entry")); - let key: ClassInstanceRef = jvm.invoke_virtual(entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; Ok((object_to_optional_string(jvm, &key).await?, object_to_optional_string(jvm, &value).await?)) } @@ -221,12 +229,16 @@ async fn entry_to_optional_strings(jvm: &Jvm, entry: &ClassInstanceRef) async fn iterator_to_entry_pairs(jvm: &Jvm, iterator: &ClassInstanceRef) -> Result, Option)>> { let mut entries = Vec::new(); loop { - let has_next: bool = jvm.invoke_virtual(iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; if !has_next { break; } - let entry: ClassInstanceRef = jvm.invoke_virtual(iterator, "next", "()Ljava/lang/Object;", ()).await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; entries.push(entry_to_optional_strings(jvm, &entry).await?); } @@ -234,7 +246,9 @@ async fn iterator_to_entry_pairs(jvm: &Jvm, iterator: &ClassInstanceRef) } async fn assert_next_throws_no_such_element(jvm: &Jvm, iterator: &ClassInstanceRef) -> Result<()> { - let result: Result> = jvm.invoke_virtual(iterator, "next", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; @@ -244,7 +258,9 @@ async fn assert_next_throws_no_such_element(jvm: &Jvm, iterator: &ClassInstanceR } async fn assert_remove_throws_unsupported(jvm: &Jvm, iterator: &ClassInstanceRef) -> Result<()> { - let result: Result<()> = jvm.invoke_virtual(iterator, "remove", "()V", ()).await; + let result: Result<()> = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; @@ -271,9 +287,13 @@ async fn test_hash_map_basic_put_get_overwrite_and_remove() -> Result<()> { assert!(jvm.is_instance(&*hash_map, "java/util/Map")); assert!(jvm.is_instance(&*hash_map, "java/util/AbstractMap")); - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let is_empty: bool = jvm.invoke_virtual(&hash_map, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); let key = JavaLangString::from_rust_string(&jvm, "key").await?; @@ -284,18 +304,31 @@ async fn test_hash_map_basic_put_get_overwrite_and_remove() -> Result<()> { let replacement = JavaLangString::from_rust_string(&jvm, "replacement").await?; let absent: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (missing_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (missing_key.clone(),), + ) .await?; assert!(absent.is_null()); let absent: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (missing_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (missing_key.clone(),), + ) .await?; assert!(absent.is_null()); let old: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value.clone()), @@ -303,28 +336,51 @@ async fn test_hash_map_basic_put_get_overwrite_and_remove() -> Result<()> { .await?; assert!(old.is_null()); - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 1); - let is_empty: bool = jvm.invoke_virtual(&hash_map, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(!is_empty); let found: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (equal_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (equal_key.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "value"); let contains_key: bool = jvm - .invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (equal_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (equal_key.clone(),), + ) .await?; assert!(contains_key); let contains_value: bool = jvm - .invoke_virtual(&hash_map, "containsValue", "(Ljava/lang/Object;)Z", (equal_value.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (equal_value.clone(),), + ) .await?; assert!(contains_value); let old: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (equal_key.clone(), replacement.clone()), @@ -332,28 +388,56 @@ async fn test_hash_map_basic_put_get_overwrite_and_remove() -> Result<()> { .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &old).await?, "value"); - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 1); let found: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "replacement"); let removed: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (equal_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (equal_key.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "replacement"); - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); let contains_key: bool = jvm - .invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (key.clone(),), + ) .await?; assert!(!contains_key); let found: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) .await?; assert!(found.is_null()); @@ -381,14 +465,26 @@ async fn test_hash_map_remove_unlinks_collision_chain_positions() -> Result<()> for (key, value) in [(key1, value1.clone()), (key2, value2.clone()), (key3, value3.clone())] { let old: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; assert!(old.is_null()); } let remove_middle = jvm.new_class("HashMapCollisionKey", "(I)V", (2,)).await?; let removed: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (remove_middle,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (remove_middle,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "value-2"); @@ -396,35 +492,75 @@ async fn test_hash_map_remove_unlinks_collision_chain_positions() -> Result<()> let query2 = jvm.new_class("HashMapCollisionKey", "(I)V", (2,)).await?; let query3 = jvm.new_class("HashMapCollisionKey", "(I)V", (3,)).await?; let found1: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (query1.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query1.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found1).await?, "value-1"); let found2: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (query2,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query2,), + ) .await?; assert!(found2.is_null()); let found3: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (query3.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query3.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found3).await?, "value-3"); - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 2); let removed: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (query3,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query3,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "value-3"); let removed: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (query1.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query1.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "value-1"); - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); let found1: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (query1,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query1,), + ) .await?; assert!(found1.is_null()); @@ -443,6 +579,7 @@ async fn test_hash_map_null_key_and_null_value() -> Result<()> { let old: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_ref.clone(), null_key_value.clone()), @@ -451,18 +588,31 @@ async fn test_hash_map_null_key_and_null_value() -> Result<()> { assert!(old.is_null()); let contains_key: bool = jvm - .invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await?; assert!(contains_key); let found: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (null_ref.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (null_ref.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "null-key-value"); let old: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_value_key.clone(), null_ref.clone()), @@ -471,26 +621,58 @@ async fn test_hash_map_null_key_and_null_value() -> Result<()> { assert!(old.is_null()); let found: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (null_value_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (null_value_key.clone(),), + ) .await?; assert!(found.is_null()); let contains_key: bool = jvm - .invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (null_value_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (null_value_key.clone(),), + ) .await?; assert!(contains_key); let contains_value: bool = jvm - .invoke_virtual(&hash_map, "containsValue", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await?; assert!(contains_value); let removed: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (null_ref.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (null_ref.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "null-key-value"); - let contains_key: bool = jvm.invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (null_ref,)).await?; + let contains_key: bool = jvm + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (null_ref,), + ) + .await?; assert!(!contains_key); Ok(()) @@ -508,13 +690,20 @@ async fn test_hash_map_zero_and_negative_capacity() -> Result<()> { let value = JavaLangString::from_rust_string(&jvm, "zero-value").await?; let contains_key: bool = jvm - .invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (key.clone(),), + ) .await?; assert!(!contains_key); let old: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value.clone()), @@ -526,16 +715,36 @@ async fn test_hash_map_zero_and_negative_capacity() -> Result<()> { assert!(jvm.array_length(&table).await? >= 1); let found: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "zero-value"); let removed: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "zero-value"); - let contains_key: bool = jvm.invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (key,)).await?; + let contains_key: bool = jvm + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (key,), + ) + .await?; assert!(!contains_key); let result = jvm.new_class("java/util/HashMap", "(I)V", (-1,)).await; @@ -556,18 +765,32 @@ async fn test_hash_map_rehash_keeps_entries() -> Result<()> { let key = JavaLangString::from_rust_string(&jvm, &format!("key-{index}")).await?; let value = JavaLangString::from_rust_string(&jvm, &format!("value-{index}")).await?; let old: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; assert!(old.is_null()); } - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 40); for index in 0..40 { let key = JavaLangString::from_rust_string(&jvm, &format!("key-{index}")).await?; let value: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, format!("value-{index}")); } @@ -588,6 +811,7 @@ async fn test_hash_map_clear_removes_entries_and_bucket_chains() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (first_key.clone(), first_value.clone()), @@ -596,29 +820,54 @@ async fn test_hash_map_clear_removes_entries_and_bucket_chains() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (second_key.clone(), second_value.clone()), ) .await?; - let _: () = jvm.invoke_virtual(&hash_map, "clear", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "clear", "()V", ()) + .await?; - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let is_empty: bool = jvm.invoke_virtual(&hash_map, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); let found: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (first_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (first_key.clone(),), + ) .await?; assert!(found.is_null()); let contains_key: bool = jvm - .invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (first_key,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (first_key,), + ) .await?; assert!(!contains_key); let contains_value: bool = jvm - .invoke_virtual(&hash_map, "containsValue", "(Ljava/lang/Object;)Z", (second_value,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (second_value,), + ) .await?; assert!(!contains_value); @@ -650,18 +899,30 @@ async fn test_hash_map_entry_direct_methods_and_assignability() -> Result<()> { assert!(jvm.is_instance(&**entry, "java/util/Map$Entry")); - let found_key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; + let found_key: ClassInstanceRef = jvm + .invoke_virtual(&entry, "java/util/HashMap$Entry", "getKey", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found_key).await?, "entry-key"); - let found_value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let found_value: ClassInstanceRef = jvm + .invoke_virtual(&entry, "java/util/HashMap$Entry", "getValue", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found_value).await?, "entry-value"); let old_value: ClassInstanceRef = jvm - .invoke_virtual(&entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (replacement.clone(),)) + .invoke_virtual( + &entry, + "java/util/HashMap$Entry", + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (replacement.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &old_value).await?, "entry-value"); - let found_value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let found_value: ClassInstanceRef = jvm + .invoke_virtual(&entry, "java/util/HashMap$Entry", "getValue", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found_value).await?, "entry-replacement"); Ok(()) @@ -691,6 +952,7 @@ async fn test_hash_map_uses_query_key_equals_direction() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (stored_key, value.clone()), @@ -698,21 +960,41 @@ async fn test_hash_map_uses_query_key_equals_direction() -> Result<()> { .await?; let contains_key: bool = jvm - .invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (query_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (query_key.clone(),), + ) .await?; assert!(contains_key); let found: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (query_key.clone(),)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query_key.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "direction-value"); let removed: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (query_key,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query_key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "direction-value"); - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); Ok(()) @@ -733,37 +1015,64 @@ async fn test_hash_map_key_set_view_backing_and_iterator_snapshot() -> Result<() for (key, value) in [(first_key.clone(), first_value), (second_key.clone(), second_value)] { let old: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; assert!(old.is_null()); } - let key_set: ClassInstanceRef = jvm.invoke_virtual(&hash_map, "keySet", "()Ljava/util/Set;", ()).await?; + let key_set: ClassInstanceRef = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; assert!(jvm.is_instance(&**key_set, "java/util/Set")); assert!(jvm.is_instance(&**key_set, "java/util/Collection")); assert!(jvm.is_instance(&**key_set, "java/util/AbstractSet")); - let size: i32 = jvm.invoke_virtual(&key_set, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 2); let contains: bool = jvm - .invoke_virtual(&key_set, "contains", "(Ljava/lang/Object;)Z", (first_key.clone(),)) + .invoke_virtual( + &key_set, + &key_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (first_key.clone(),), + ) .await?; assert!(contains); let contains: bool = jvm - .invoke_virtual(&key_set, "contains", "(Ljava/lang/Object;)Z", (missing_key.clone(),)) + .invoke_virtual( + &key_set, + &key_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (missing_key.clone(),), + ) .await?; assert!(!contains); - let key_array: ClassInstanceRef> = jvm.invoke_virtual(&key_set, "toArray", "()[Ljava/lang/Object;", ()).await?; + let key_array: ClassInstanceRef> = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let key_array_values = sorted_optional_strings(object_array_to_optional_strings(&jvm, &key_array).await?); assert_eq!(key_array_values, vec![Some("first".to_string()), Some("second".to_string())]); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&key_set, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; assert_eq!(iterator.class_definition().name(), "java/util/HashMap$KeyIterator"); assert!(jvm.is_instance(&**iterator, "java/util/Iterator")); let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (third_key.clone(), third_value), @@ -775,10 +1084,18 @@ async fn test_hash_map_key_set_view_backing_and_iterator_snapshot() -> Result<() assert_next_throws_no_such_element(&jvm, &iterator).await?; assert_remove_throws_unsupported(&jvm, &iterator).await?; - let size: i32 = jvm.invoke_virtual(&key_set, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 3); let contains: bool = jvm - .invoke_virtual(&key_set, "contains", "(Ljava/lang/Object;)Z", (third_key.clone(),)) + .invoke_virtual( + &key_set, + &key_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (third_key.clone(),), + ) .await?; assert!(contains); @@ -787,6 +1104,7 @@ async fn test_hash_map_key_set_view_backing_and_iterator_snapshot() -> Result<() let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_value_key.clone(), null_ref), @@ -794,32 +1112,74 @@ async fn test_hash_map_key_set_view_backing_and_iterator_snapshot() -> Result<() .await?; let removed: bool = jvm - .invoke_virtual(&key_set, "remove", "(Ljava/lang/Object;)Z", (second_key.clone(),)) + .invoke_virtual( + &key_set, + &key_set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (second_key.clone(),), + ) .await?; assert!(removed); let removed: bool = jvm - .invoke_virtual(&key_set, "remove", "(Ljava/lang/Object;)Z", (null_value_key.clone(),)) + .invoke_virtual( + &key_set, + &key_set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (null_value_key.clone(),), + ) .await?; assert!(removed); - let removed: bool = jvm.invoke_virtual(&key_set, "remove", "(Ljava/lang/Object;)Z", (missing_key,)).await?; + let removed: bool = jvm + .invoke_virtual( + &key_set, + &key_set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (missing_key,), + ) + .await?; assert!(!removed); let contains_key: bool = jvm - .invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (second_key,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (second_key,), + ) .await?; assert!(!contains_key); let contains_key: bool = jvm - .invoke_virtual(&hash_map, "containsKey", "(Ljava/lang/Object;)Z", (null_value_key,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (null_value_key,), + ) .await?; assert!(!contains_key); - let _: () = jvm.invoke_virtual(&key_set, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let _: () = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "clear", "()V", ()) + .await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let is_empty: bool = jvm.invoke_virtual(&key_set, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); - let empty_iterator: ClassInstanceRef = jvm.invoke_virtual(&key_set, "iterator", "()Ljava/util/Iterator;", ()).await?; - let has_next: bool = jvm.invoke_virtual(&empty_iterator, "hasNext", "()Z", ()).await?; + let empty_iterator: ClassInstanceRef = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let has_next: bool = jvm + .invoke_virtual(&empty_iterator, &empty_iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; assert!(!has_next); assert_next_throws_no_such_element(&jvm, &empty_iterator).await?; @@ -843,6 +1203,7 @@ async fn test_hash_map_values_view_contains_clear_and_iterator_snapshot() -> Res let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_value_key, null_ref.clone()), @@ -851,39 +1212,67 @@ async fn test_hash_map_values_view_contains_clear_and_iterator_snapshot() -> Res let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (equal_value_key, equal_value), ) .await?; - let values: ClassInstanceRef = jvm.invoke_virtual(&hash_map, "values", "()Ljava/util/Collection;", ()).await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; assert!(jvm.is_instance(&**values, "java/util/Collection")); assert!(jvm.is_instance(&**values, "java/util/AbstractCollection")); assert!(!jvm.is_instance(&**values, "java/util/Set")); - let size: i32 = jvm.invoke_virtual(&values, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&values, &values.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 2); let contains_null: bool = jvm - .invoke_virtual(&values, "contains", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &values, + &values.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await?; assert!(contains_null); let contains_equal: bool = jvm - .invoke_virtual(&values, "contains", "(Ljava/lang/Object;)Z", (equal_value_distinct.clone(),)) + .invoke_virtual( + &values, + &values.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (equal_value_distinct.clone(),), + ) .await?; assert!(contains_equal); - let contains_missing: bool = jvm.invoke_virtual(&values, "contains", "(Ljava/lang/Object;)Z", (missing_value,)).await?; + let contains_missing: bool = jvm + .invoke_virtual( + &values, + &values.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (missing_value,), + ) + .await?; assert!(!contains_missing); - let values_array: ClassInstanceRef> = jvm.invoke_virtual(&values, "toArray", "()[Ljava/lang/Object;", ()).await?; + let values_array: ClassInstanceRef> = jvm + .invoke_virtual(&values, &values.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let values_array = sorted_optional_strings(object_array_to_optional_strings(&jvm, &values_array).await?); assert_eq!(values_array, vec![None, Some("same-value".to_string())]); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&values, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&values, &values.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; assert_eq!(iterator.class_definition().name(), "java/util/HashMap$ValueIterator"); let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (third_key, third_value), @@ -895,16 +1284,22 @@ async fn test_hash_map_values_view_contains_clear_and_iterator_snapshot() -> Res assert_next_throws_no_such_element(&jvm, &iterator).await?; assert_remove_throws_unsupported(&jvm, &iterator).await?; - let size: i32 = jvm.invoke_virtual(&values, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&values, &values.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 3); - let _: () = jvm.invoke_virtual(&values, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let _: () = jvm.invoke_virtual(&values, &values.class_definition().name(), "clear", "()V", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let is_empty: bool = jvm.invoke_virtual(&values, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&values, &values.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); - let values_array: ClassInstanceRef> = jvm.invoke_virtual(&values, "toArray", "()[Ljava/lang/Object;", ()).await?; + let values_array: ClassInstanceRef> = jvm + .invoke_virtual(&values, &values.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; assert_eq!(jvm.array_length(&values_array).await?, 0); Ok(()) @@ -924,27 +1319,42 @@ async fn test_hash_map_entry_set_view_backing_clear_and_iterator_snapshot() -> R for (key, value) in [(first_key.clone(), first_value), (second_key.clone(), second_value)] { let old: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; assert!(old.is_null()); } - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&hash_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; assert!(jvm.is_instance(&**entry_set, "java/util/Set")); assert!(jvm.is_instance(&**entry_set, "java/util/Collection")); assert!(jvm.is_instance(&**entry_set, "java/util/AbstractSet")); - let size: i32 = jvm.invoke_virtual(&entry_set, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 2); - let is_empty: bool = jvm.invoke_virtual(&entry_set, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(!is_empty); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entry_set, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; assert_eq!(iterator.class_definition().name(), "java/util/HashMap$EntryIterator"); assert!(jvm.is_instance(&**iterator, "java/util/Iterator")); let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (third_key, third_value), @@ -962,17 +1372,29 @@ async fn test_hash_map_entry_set_view_backing_clear_and_iterator_snapshot() -> R assert_next_throws_no_such_element(&jvm, &iterator).await?; assert_remove_throws_unsupported(&jvm, &iterator).await?; - let size: i32 = jvm.invoke_virtual(&entry_set, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 3); - let _: () = jvm.invoke_virtual(&entry_set, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&hash_map, "size", "()I", ()).await?; + let _: () = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "clear", "()V", ()) + .await?; + let size: i32 = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let is_empty: bool = jvm.invoke_virtual(&entry_set, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); - let empty_iterator: ClassInstanceRef = jvm.invoke_virtual(&entry_set, "iterator", "()Ljava/util/Iterator;", ()).await?; - let has_next: bool = jvm.invoke_virtual(&empty_iterator, "hasNext", "()Z", ()).await?; + let empty_iterator: ClassInstanceRef = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let has_next: bool = jvm + .invoke_virtual(&empty_iterator, &empty_iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; assert!(!has_next); assert_next_throws_no_such_element(&jvm, &empty_iterator).await?; @@ -990,28 +1412,49 @@ async fn test_hash_map_entry_set_iterator_set_value_updates_backing_map() -> Res let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value.clone()), ) .await?; - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&hash_map, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entry_set, "iterator", "()Ljava/util/Iterator;", ()).await?; - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert!(jvm.is_instance(&**entry, "java/util/Map$Entry")); let old_value: ClassInstanceRef = jvm - .invoke_virtual(&entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (replacement.clone(),)) + .invoke_virtual( + &entry, + &entry.class_definition().name(), + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (replacement.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &old_value).await?, "old-value"); let found: ClassInstanceRef = jvm - .invoke_virtual(&hash_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual( + &hash_map, + &hash_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "new-value"); - let entry_value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let entry_value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &entry_value).await?, "new-value"); Ok(()) @@ -1027,23 +1470,42 @@ async fn test_hash_map_entry_set_contains_candidates_and_null_values() -> Result let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value.clone()), ) .await?; - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&hash_map, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entry_set, "iterator", "()Ljava/util/Iterator;", ()).await?; - let backing_entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let backing_entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let contains: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (backing_entry.clone(),)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (backing_entry.clone(),), + ) .await?; assert!(contains); let null_ref: ClassInstanceRef = None.into(); let contains: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await?; assert!(!contains); @@ -1059,7 +1521,13 @@ async fn test_hash_map_entry_set_contains_candidates_and_null_values() -> Result .await? .into(); let contains: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (candidate_equal,)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (candidate_equal,), + ) .await?; assert!(contains); @@ -1074,7 +1542,13 @@ async fn test_hash_map_entry_set_contains_candidates_and_null_values() -> Result .await? .into(); let contains: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (candidate_different_value,)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (candidate_different_value,), + ) .await?; assert!(!contains); @@ -1089,7 +1563,13 @@ async fn test_hash_map_entry_set_contains_candidates_and_null_values() -> Result .await? .into(); let contains: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (candidate_null_for_non_null_value,)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (candidate_null_for_non_null_value,), + ) .await?; assert!(!contains); @@ -1098,6 +1578,7 @@ async fn test_hash_map_entry_set_contains_candidates_and_null_values() -> Result let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_ref.clone(), null_key_value), @@ -1114,7 +1595,13 @@ async fn test_hash_map_entry_set_contains_candidates_and_null_values() -> Result .await? .into(); let contains: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (candidate_null_key,)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (candidate_null_key,), + ) .await?; assert!(contains); @@ -1123,6 +1610,7 @@ async fn test_hash_map_entry_set_contains_candidates_and_null_values() -> Result let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_value_key, null_ref.clone()), @@ -1139,12 +1627,26 @@ async fn test_hash_map_entry_set_contains_candidates_and_null_values() -> Result .await? .into(); let contains: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (candidate_null_value,)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (candidate_null_value,), + ) .await?; assert!(contains); let non_entry = JavaLangString::from_rust_string(&jvm, "not-an-entry").await?; - let contains: bool = jvm.invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (non_entry,)).await?; + let contains: bool = jvm + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (non_entry,), + ) + .await?; assert!(!contains); Ok(()) @@ -1167,13 +1669,16 @@ async fn test_hash_map_entry_set_contains_custom_map_entry() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &hash_map, + &hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value.clone()), ) .await?; - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&hash_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&hash_map, &hash_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; let equal_key = JavaLangString::from_rust_string(&jvm, "custom-key").await?; let equal_value = JavaLangString::from_rust_string(&jvm, "custom-value").await?; let custom_equal = jvm @@ -1182,7 +1687,13 @@ async fn test_hash_map_entry_set_contains_custom_map_entry() -> Result<()> { assert!(jvm.is_instance(&*custom_equal, "java/util/Map$Entry")); let contains: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (custom_equal,)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (custom_equal,), + ) .await?; assert!(contains); @@ -1192,7 +1703,13 @@ async fn test_hash_map_entry_set_contains_custom_map_entry() -> Result<()> { .new_class("CustomMapEntry", "(Ljava/lang/Object;Ljava/lang/Object;)V", (equal_key, different_value)) .await?; let contains: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (custom_different,)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (custom_different,), + ) .await?; assert!(!contains); diff --git a/java_runtime/tests/classes/java/util/test_hash_set.rs b/java_runtime/tests/classes/java/util/test_hash_set.rs index fe479db5..bb2c7077 100644 --- a/java_runtime/tests/classes/java/util/test_hash_set.rs +++ b/java_runtime/tests/classes/java/util/test_hash_set.rs @@ -25,12 +25,16 @@ async fn object_array_to_optional_strings(jvm: &jvm::Jvm, array: &ClassInstanceR async fn iterator_to_optional_strings(jvm: &jvm::Jvm, iterator: &ClassInstanceRef) -> Result>> { let mut values = Vec::new(); loop { - let has_next: bool = jvm.invoke_virtual(iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; if !has_next { break; } - let value: ClassInstanceRef = jvm.invoke_virtual(iterator, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; values.push(object_to_optional_string(jvm, &value).await?); } @@ -38,7 +42,9 @@ async fn iterator_to_optional_strings(jvm: &jvm::Jvm, iterator: &ClassInstanceRe } async fn assert_next_throws_no_such_element(jvm: &jvm::Jvm, iterator: &ClassInstanceRef) -> Result<()> { - let result: Result> = jvm.invoke_virtual(iterator, "next", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; @@ -48,7 +54,9 @@ async fn assert_next_throws_no_such_element(jvm: &jvm::Jvm, iterator: &ClassInst } async fn assert_remove_throws_unsupported(jvm: &jvm::Jvm, iterator: &ClassInstanceRef) -> Result<()> { - let result: Result<()> = jvm.invoke_virtual(iterator, "remove", "()V", ()).await; + let result: Result<()> = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; @@ -80,67 +88,169 @@ async fn test_hash_set_add_duplicate_contains_remove_null_and_clear() -> Result< let missing = JavaLangString::from_rust_string(&jvm, "missing").await?; let null_ref: ClassInstanceRef = None.into(); - let added: bool = jvm.invoke_virtual(&hash_set, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let added: bool = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; assert!(added); let added: bool = jvm - .invoke_virtual(&hash_set, "add", "(Ljava/lang/Object;)Z", (equal_value.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (equal_value.clone(),), + ) .await?; assert!(!added); let contains: bool = jvm - .invoke_virtual(&hash_set, "contains", "(Ljava/lang/Object;)Z", (equal_value.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (equal_value.clone(),), + ) .await?; assert!(contains); let contains: bool = jvm - .invoke_virtual(&hash_set, "contains", "(Ljava/lang/Object;)Z", (missing.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (missing.clone(),), + ) .await?; assert!(!contains); - let added_null: bool = jvm.invoke_virtual(&hash_set, "add", "(Ljava/lang/Object;)Z", (null_ref.clone(),)).await?; + let added_null: bool = jvm + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) + .await?; assert!(added_null); - let added_null: bool = jvm.invoke_virtual(&hash_set, "add", "(Ljava/lang/Object;)Z", (null_ref.clone(),)).await?; + let added_null: bool = jvm + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) + .await?; assert!(!added_null); let contains_null: bool = jvm - .invoke_virtual(&hash_set, "contains", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await?; assert!(contains_null); - let size: i32 = jvm.invoke_virtual(&hash_set, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 2); - let is_empty: bool = jvm.invoke_virtual(&hash_set, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(!is_empty); let removed: bool = jvm - .invoke_virtual(&hash_set, "remove", "(Ljava/lang/Object;)Z", (equal_value.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (equal_value.clone(),), + ) .await?; assert!(removed); - let removed: bool = jvm.invoke_virtual(&hash_set, "remove", "(Ljava/lang/Object;)Z", (equal_value,)).await?; + let removed: bool = jvm + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (equal_value,), + ) + .await?; assert!(!removed); - let removed_missing: bool = jvm.invoke_virtual(&hash_set, "remove", "(Ljava/lang/Object;)Z", (missing,)).await?; + let removed_missing: bool = jvm + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (missing,), + ) + .await?; assert!(!removed_missing); let removed_null: bool = jvm - .invoke_virtual(&hash_set, "remove", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await?; assert!(removed_null); let removed_null: bool = jvm - .invoke_virtual(&hash_set, "remove", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await?; assert!(!removed_null); let contains_null: bool = jvm - .invoke_virtual(&hash_set, "contains", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await?; assert!(!contains_null); - let size: i32 = jvm.invoke_virtual(&hash_set, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let _: () = jvm.invoke_virtual(&hash_set, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&hash_set, "size", "()I", ()).await?; + let _: () = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "clear", "()V", ()) + .await?; + let size: i32 = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let is_empty: bool = jvm.invoke_virtual(&hash_set, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); - let contains_null: bool = jvm.invoke_virtual(&hash_set, "contains", "(Ljava/lang/Object;)Z", (null_ref,)).await?; + let contains_null: bool = jvm + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null_ref,), + ) + .await?; assert!(!contains_null); Ok(()) @@ -155,29 +265,51 @@ async fn test_hash_set_to_array_and_iterator_snapshot_exhaustion_remove() -> Res let second = JavaLangString::from_rust_string(&jvm, "second").await?; let third = JavaLangString::from_rust_string(&jvm, "third").await?; - let _: bool = jvm.invoke_virtual(&hash_set, "add", "(Ljava/lang/Object;)Z", (first,)).await?; - let _: bool = jvm.invoke_virtual(&hash_set, "add", "(Ljava/lang/Object;)Z", (second,)).await?; + let _: bool = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (first,)) + .await?; + let _: bool = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (second,)) + .await?; - let array: ClassInstanceRef> = jvm.invoke_virtual(&hash_set, "toArray", "()[Ljava/lang/Object;", ()).await?; + let array: ClassInstanceRef> = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let values = sorted_optional_strings(object_array_to_optional_strings(&jvm, &array).await?); assert_eq!(values, vec![Some("first".to_string()), Some("second".to_string())]); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&hash_set, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; assert!(jvm.is_instance(&**iterator, "java/util/Iterator")); - let _: bool = jvm.invoke_virtual(&hash_set, "add", "(Ljava/lang/Object;)Z", (third,)).await?; + let _: bool = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (third,)) + .await?; let snapshot = sorted_optional_strings(iterator_to_optional_strings(&jvm, &iterator).await?); assert_eq!(snapshot, vec![Some("first".to_string()), Some("second".to_string())]); assert_next_throws_no_such_element(&jvm, &iterator).await?; assert_remove_throws_unsupported(&jvm, &iterator).await?; - let size: i32 = jvm.invoke_virtual(&hash_set, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 3); let empty_hash_set = jvm.new_class("java/util/HashSet", "()V", ()).await?; - let empty_iterator: ClassInstanceRef = jvm.invoke_virtual(&empty_hash_set, "iterator", "()Ljava/util/Iterator;", ()).await?; - let has_next: bool = jvm.invoke_virtual(&empty_iterator, "hasNext", "()Z", ()).await?; + let empty_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &empty_hash_set, + &empty_hash_set.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let has_next: bool = jvm + .invoke_virtual(&empty_iterator, &empty_iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; assert!(!has_next); assert_next_throws_no_such_element(&jvm, &empty_iterator).await?; @@ -196,21 +328,37 @@ async fn test_hash_set_zero_capacity_add_path() -> Result<()> { let value = JavaLangString::from_rust_string(&jvm, "zero-capacity").await?; let equal_value = JavaLangString::from_rust_string(&jvm, "zero-capacity").await?; - let added: bool = jvm.invoke_virtual(&hash_set, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let added: bool = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; assert!(added); let contains: bool = jvm - .invoke_virtual(&hash_set, "contains", "(Ljava/lang/Object;)Z", (equal_value.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (equal_value.clone(),), + ) .await?; assert!(contains); let added: bool = jvm - .invoke_virtual(&hash_set, "add", "(Ljava/lang/Object;)Z", (equal_value.clone(),)) + .invoke_virtual( + &hash_set, + &hash_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (equal_value.clone(),), + ) .await?; assert!(!added); let table: ClassInstanceRef> = jvm.get_field(&map, "table", "[Ljava/util/HashMap$Entry;").await?; assert!(jvm.array_length(&table).await? >= 1); - let size: i32 = jvm.invoke_virtual(&hash_set, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hash_set, &hash_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 1); let result = jvm.new_class("java/util/HashSet", "(I)V", (-1,)).await; diff --git a/java_runtime/tests/classes/java/util/test_hashtable.rs b/java_runtime/tests/classes/java/util/test_hashtable.rs index 13bd1005..8bdafcbe 100644 --- a/java_runtime/tests/classes/java/util/test_hashtable.rs +++ b/java_runtime/tests/classes/java/util/test_hashtable.rs @@ -22,6 +22,7 @@ async fn test_hashtable_cldc_legacy_api() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value.clone()), @@ -29,22 +30,52 @@ async fn test_hashtable_cldc_legacy_api() -> Result<()> { .await?; assert!( - jvm.invoke_virtual::<_, bool>(&hashtable, "contains", "(Ljava/lang/Object;)Z", (value,)) - .await? + jvm.invoke_virtual::<_, bool>( + &hashtable, + &hashtable.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (value,) + ) + .await? ); - let keys: ClassInstanceRef = jvm.invoke_virtual(&hashtable, "keys", "()Ljava/util/Enumeration;", ()).await?; - let enumerated_key: ClassInstanceRef = jvm.invoke_virtual(&keys, "nextElement", "()Ljava/lang/Object;", ()).await?; + let keys: ClassInstanceRef = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "keys", "()Ljava/util/Enumeration;", ()) + .await?; + let enumerated_key: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &enumerated_key).await?, "key"); - let elements: ClassInstanceRef = jvm.invoke_virtual(&hashtable, "elements", "()Ljava/util/Enumeration;", ()).await?; - let enumerated_value: ClassInstanceRef = jvm.invoke_virtual(&elements, "nextElement", "()Ljava/lang/Object;", ()).await?; + let elements: ClassInstanceRef = jvm + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "elements", + "()Ljava/util/Enumeration;", + (), + ) + .await?; + let enumerated_value: ClassInstanceRef = jvm + .invoke_virtual(&elements, &elements.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &enumerated_value).await?, "value"); - let _: () = jvm.invoke_virtual(&hashtable, "rehash", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "rehash", "()V", ()) + .await?; let found: ClassInstanceRef = jvm - .invoke_virtual(&hashtable, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "value"); - let text: ClassInstanceRef = jvm.invoke_virtual(&hashtable, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "{key=value}"); let result = jvm.new_class("java/util/Hashtable", "(I)V", (-1,)).await; @@ -59,12 +90,16 @@ async fn test_hashtable_cldc_legacy_api() -> Result<()> { async fn iterator_to_optional_strings(jvm: &Jvm, iterator: &ClassInstanceRef) -> Result>> { let mut values = Vec::new(); loop { - let has_next: bool = jvm.invoke_virtual(iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; if !has_next { break; } - let value: ClassInstanceRef = jvm.invoke_virtual(iterator, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; values.push(object_to_optional_string(jvm, &value).await?); } @@ -72,7 +107,9 @@ async fn iterator_to_optional_strings(jvm: &Jvm, iterator: &ClassInstanceRef) -> Result<()> { - let result: Result> = jvm.invoke_virtual(iterator, "next", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; @@ -82,7 +119,9 @@ async fn assert_next_throws_no_such_element(jvm: &Jvm, iterator: &ClassInstanceR } async fn assert_remove_throws_unsupported(jvm: &Jvm, iterator: &ClassInstanceRef) -> Result<()> { - let result: Result<()> = jvm.invoke_virtual(iterator, "remove", "()V", ()).await; + let result: Result<()> = jvm + .invoke_virtual(iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; @@ -113,9 +152,13 @@ async fn test_hashtable_map_views_and_legacy_operations() -> Result<()> { assert!(jvm.is_instance(&*hashtable, "java/util/Map")); assert!(jvm.is_instance(&*hashtable, "java/util/Dictionary")); - let size: i32 = jvm.invoke_virtual(&hashtable, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let is_empty: bool = jvm.invoke_virtual(&hashtable, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); let test_key = JavaLangString::from_rust_string(&jvm, "testKey").await?; @@ -126,6 +169,7 @@ async fn test_hashtable_map_views_and_legacy_operations() -> Result<()> { let old: ClassInstanceRef = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (test_key.clone(), test_value.clone()), @@ -135,6 +179,7 @@ async fn test_hashtable_map_views_and_legacy_operations() -> Result<()> { let old: ClassInstanceRef = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (second_key.clone(), second_value.clone()), @@ -142,13 +187,23 @@ async fn test_hashtable_map_views_and_legacy_operations() -> Result<()> { .await?; assert!(old.is_null()); - let size: i32 = jvm.invoke_virtual(&hashtable, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 2); - let is_empty: bool = jvm.invoke_virtual(&hashtable, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(!is_empty); let value = jvm - .invoke_virtual(&hashtable, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (test_key.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (test_key.clone(),), + ) .await?; let value_string = JavaLangString::to_rust_string(&jvm, &value).await?; @@ -157,19 +212,32 @@ async fn test_hashtable_map_views_and_legacy_operations() -> Result<()> { let test_key_second = JavaLangString::from_rust_string(&jvm, "testKey").await?; let value = jvm - .invoke_virtual(&hashtable, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (test_key_second.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (test_key_second.clone(),), + ) .await?; let value_string = JavaLangString::to_rust_string(&jvm, &value).await?; assert_eq!(value_string, "testValue"); let contains_key: bool = jvm - .invoke_virtual(&hashtable, "containsKey", "(Ljava/lang/Object;)Z", (test_key_second.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (test_key_second.clone(),), + ) .await?; assert!(contains_key); let contains_value: bool = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "containsValue", "(Ljava/lang/Object;)Z", (JavaLangString::from_rust_string(&jvm, "testValue").await?,), @@ -177,22 +245,40 @@ async fn test_hashtable_map_views_and_legacy_operations() -> Result<()> { .await?; assert!(contains_value); - let key_set: ClassInstanceRef = jvm.invoke_virtual(&hashtable, "keySet", "()Ljava/util/Set;", ()).await?; + let key_set: ClassInstanceRef = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; assert!(jvm.is_instance(&**key_set, "java/util/Set")); assert!(jvm.is_instance(&**key_set, "java/util/Collection")); assert!(jvm.is_instance(&**key_set, "java/util/AbstractSet")); - let key_set_size: i32 = jvm.invoke_virtual(&key_set, "size", "()I", ()).await?; + let key_set_size: i32 = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(key_set_size, 2); let contains_key: bool = jvm - .invoke_virtual(&key_set, "contains", "(Ljava/lang/Object;)Z", (test_key_second.clone(),)) + .invoke_virtual( + &key_set, + &key_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (test_key_second.clone(),), + ) .await?; assert!(contains_key); let missing_key = JavaLangString::from_rust_string(&jvm, "missing").await?; let contains_key: bool = jvm - .invoke_virtual(&key_set, "contains", "(Ljava/lang/Object;)Z", (missing_key.clone(),)) + .invoke_virtual( + &key_set, + &key_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (missing_key.clone(),), + ) .await?; assert!(!contains_key); - let key_iterator: ClassInstanceRef = jvm.invoke_virtual(&key_set, "iterator", "()Ljava/util/Iterator;", ()).await?; + let key_iterator: ClassInstanceRef = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; assert_eq!(key_iterator.class_definition().name(), "java/util/Hashtable$Enumerator"); assert!(jvm.is_instance(&**key_iterator, "java/util/Iterator")); let key_snapshot = sorted_optional_strings(iterator_to_optional_strings(&jvm, &key_iterator).await?); @@ -200,121 +286,213 @@ async fn test_hashtable_map_views_and_legacy_operations() -> Result<()> { assert_next_throws_no_such_element(&jvm, &key_iterator).await?; assert_remove_throws_unsupported(&jvm, &key_iterator).await?; - let values: ClassInstanceRef = jvm.invoke_virtual(&hashtable, "values", "()Ljava/util/Collection;", ()).await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; assert!(jvm.is_instance(&**values, "java/util/Collection")); assert!(jvm.is_instance(&**values, "java/util/AbstractCollection")); - let values_size: i32 = jvm.invoke_virtual(&values, "size", "()I", ()).await?; + let values_size: i32 = jvm.invoke_virtual(&values, &values.class_definition().name(), "size", "()I", ()).await?; assert_eq!(values_size, 2); let contains_value: bool = jvm .invoke_virtual( &values, + &values.class_definition().name(), "contains", "(Ljava/lang/Object;)Z", (JavaLangString::from_rust_string(&jvm, "secondValue").await?,), ) .await?; assert!(contains_value); - let values_iterator: ClassInstanceRef = jvm.invoke_virtual(&values, "iterator", "()Ljava/util/Iterator;", ()).await?; + let values_iterator: ClassInstanceRef = jvm + .invoke_virtual(&values, &values.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; assert_eq!(values_iterator.class_definition().name(), "java/util/Hashtable$Enumerator"); let values_snapshot = sorted_optional_strings(iterator_to_optional_strings(&jvm, &values_iterator).await?); assert_eq!(values_snapshot, vec![Some("secondValue".to_string()), Some("testValue".to_string())]); - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&hashtable, "entrySet", "()Ljava/util/Set;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; assert!(jvm.is_instance(&**entry_set, "java/util/Set")); assert!(jvm.is_instance(&**entry_set, "java/util/Collection")); assert!(jvm.is_instance(&**entry_set, "java/util/AbstractSet")); - let entry_set_size: i32 = jvm.invoke_virtual(&entry_set, "size", "()I", ()).await?; + let entry_set_size: i32 = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(entry_set_size, 2); - let entry_iterator: ClassInstanceRef = jvm.invoke_virtual(&entry_set, "iterator", "()Ljava/util/Iterator;", ()).await?; + let entry_iterator: ClassInstanceRef = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; assert_eq!(entry_iterator.class_definition().name(), "java/util/Hashtable$Enumerator"); assert!(jvm.is_instance(&**entry_iterator, "java/util/Iterator")); - let entry: ClassInstanceRef = jvm.invoke_virtual(&entry_iterator, "next", "()Ljava/lang/Object;", ()).await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual( + &entry_iterator, + &entry_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; assert!(jvm.is_instance(&**entry, "java/util/Map$Entry")); let contains_entry: bool = jvm - .invoke_virtual(&entry_set, "contains", "(Ljava/lang/Object;)Z", (entry.clone(),)) + .invoke_virtual( + &entry_set, + &entry_set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (entry.clone(),), + ) .await?; assert!(contains_entry); - let entry_key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let entry_value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + let entry_key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let entry_value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; assert!(!entry_key.is_null()); assert!(!entry_value.is_null()); let replacement = JavaLangString::from_rust_string(&jvm, "replacementValue").await?; let old_value: ClassInstanceRef = jvm - .invoke_virtual(&entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (replacement.clone(),)) + .invoke_virtual( + &entry, + &entry.class_definition().name(), + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (replacement.clone(),), + ) .await?; assert!(!old_value.is_null()); let backing_value: ClassInstanceRef = jvm - .invoke_virtual(&hashtable, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (entry_key.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (entry_key.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &backing_value).await?, "replacementValue"); let value: ClassInstanceRef = jvm - .invoke_virtual(&hashtable, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (test_key.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (test_key.clone(),), + ) .await?; assert!(!value.is_null()); let value: ClassInstanceRef = jvm - .invoke_virtual(&hashtable, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (test_key.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (test_key.clone(),), + ) .await?; assert!(value.is_null()); - let size: i32 = jvm.invoke_virtual(&hashtable, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 1); - let _: () = jvm.invoke_virtual(&hashtable, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&hashtable, "size", "()I", ()).await?; + let _: () = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "clear", "()V", ()) + .await?; + let size: i32 = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); - let is_empty: bool = jvm.invoke_virtual(&hashtable, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); let value: ClassInstanceRef = jvm - .invoke_virtual(&hashtable, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (second_key.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (second_key.clone(),), + ) .await?; assert!(value.is_null()); let contains_key: bool = jvm - .invoke_virtual(&hashtable, "containsKey", "(Ljava/lang/Object;)Z", (second_key.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (second_key.clone(),), + ) .await?; assert!(!contains_key); let contains_value: bool = jvm - .invoke_virtual(&hashtable, "containsValue", "(Ljava/lang/Object;)Z", (second_value.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (second_value.clone(),), + ) .await?; assert!(!contains_value); let _: ClassInstanceRef = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (test_key.clone(), test_value.clone()), ) .await?; - let _: () = jvm.invoke_virtual(&key_set, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&hashtable, "size", "()I", ()).await?; + let _: () = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "clear", "()V", ()) + .await?; + let size: i32 = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); let _: ClassInstanceRef = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (test_key.clone(), test_value.clone()), ) .await?; - let _: () = jvm.invoke_virtual(&values, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&hashtable, "size", "()I", ()).await?; + let _: () = jvm.invoke_virtual(&values, &values.class_definition().name(), "clear", "()V", ()).await?; + let size: i32 = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); let _: ClassInstanceRef = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (test_key.clone(), test_value), ) .await?; - let _: () = jvm.invoke_virtual(&entry_set, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&hashtable, "size", "()I", ()).await?; + let _: () = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "clear", "()V", ()) + .await?; + let size: i32 = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 0); Ok(()) @@ -331,6 +509,7 @@ async fn test_hashtable_legacy_null_and_snapshot_edges() -> Result<()> { let result: Result> = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_ref.clone(), value.clone()), @@ -338,11 +517,23 @@ async fn test_hashtable_legacy_null_and_snapshot_edges() -> Result<()> { .await; assert_null_pointer_exception(&jvm, result).await?; let result: Result> = jvm - .invoke_virtual(&hashtable, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (null_ref.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (null_ref.clone(),), + ) .await; assert_null_pointer_exception(&jvm, result).await?; let result: Result = jvm - .invoke_virtual(&hashtable, "containsKey", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await; assert_null_pointer_exception(&jvm, result).await?; @@ -350,6 +541,7 @@ async fn test_hashtable_legacy_null_and_snapshot_edges() -> Result<()> { let result: Result> = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_value_key.clone(), null_ref.clone()), @@ -360,6 +552,7 @@ async fn test_hashtable_legacy_null_and_snapshot_edges() -> Result<()> { let old: ClassInstanceRef = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null_value_key.clone(), value.clone()), @@ -368,45 +561,100 @@ async fn test_hashtable_legacy_null_and_snapshot_edges() -> Result<()> { assert!(old.is_null()); let contains_key: bool = jvm - .invoke_virtual(&hashtable, "containsKey", "(Ljava/lang/Object;)Z", (null_value_key.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (null_value_key.clone(),), + ) .await?; assert!(contains_key); let result: Result = jvm - .invoke_virtual(&hashtable, "containsValue", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await; assert_null_pointer_exception(&jvm, result).await?; - let values: ClassInstanceRef = jvm.invoke_virtual(&hashtable, "values", "()Ljava/util/Collection;", ()).await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; let result: Result = jvm - .invoke_virtual(&values, "contains", "(Ljava/lang/Object;)Z", (null_ref.clone(),)) + .invoke_virtual( + &values, + &values.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (null_ref.clone(),), + ) .await; assert_null_pointer_exception(&jvm, result).await?; - let entry_set: ClassInstanceRef = jvm.invoke_virtual(&hashtable, "entrySet", "()Ljava/util/Set;", ()).await?; - let entry_iterator: ClassInstanceRef = jvm.invoke_virtual(&entry_set, "iterator", "()Ljava/util/Iterator;", ()).await?; - let entry: ClassInstanceRef = jvm.invoke_virtual(&entry_iterator, "next", "()Ljava/lang/Object;", ()).await?; + let entry_set: ClassInstanceRef = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let entry_iterator: ClassInstanceRef = jvm + .invoke_virtual(&entry_set, &entry_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual( + &entry_iterator, + &entry_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; assert!(jvm.is_instance(&**entry, "java/util/Map$Entry")); let result: Result> = jvm - .invoke_virtual(&entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (null_ref.clone(),)) + .invoke_virtual( + &entry, + &entry.class_definition().name(), + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (null_ref.clone(),), + ) .await; assert_null_pointer_exception(&jvm, result).await?; let replacement = JavaLangString::from_rust_string(&jvm, "replacement").await?; let old_value: ClassInstanceRef = jvm - .invoke_virtual(&entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (replacement.clone(),)) + .invoke_virtual( + &entry, + &entry.class_definition().name(), + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (replacement.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &old_value).await?, "value"); let found: ClassInstanceRef = jvm - .invoke_virtual(&hashtable, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (null_value_key.clone(),)) + .invoke_virtual( + &hashtable, + &hashtable.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (null_value_key.clone(),), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "replacement"); - let key_set: ClassInstanceRef = jvm.invoke_virtual(&hashtable, "keySet", "()Ljava/util/Set;", ()).await?; - let key_iterator: ClassInstanceRef = jvm.invoke_virtual(&key_set, "iterator", "()Ljava/util/Iterator;", ()).await?; + let key_set: ClassInstanceRef = jvm + .invoke_virtual(&hashtable, &hashtable.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let key_iterator: ClassInstanceRef = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let second_key = JavaLangString::from_rust_string(&jvm, "second").await?; let second_value = JavaLangString::from_rust_string(&jvm, "second-value").await?; let _: ClassInstanceRef = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (second_key.clone(), second_value), @@ -415,7 +663,9 @@ async fn test_hashtable_legacy_null_and_snapshot_edges() -> Result<()> { let snapshot = sorted_optional_strings(iterator_to_optional_strings(&jvm, &key_iterator).await?); assert_eq!(snapshot, vec![Some("null-value-key".to_string())]); - let size: i32 = jvm.invoke_virtual(&key_set, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 2); Ok(()) diff --git a/java_runtime/tests/classes/java/util/test_linked_hash_map.rs b/java_runtime/tests/classes/java/util/test_linked_hash_map.rs index ae5ff343..499cc5e3 100644 --- a/java_runtime/tests/classes/java/util/test_linked_hash_map.rs +++ b/java_runtime/tests/classes/java/util/test_linked_hash_map.rs @@ -42,7 +42,7 @@ impl LimitedLinkedHashMap { async fn remove_eldest_entry(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef, _: ClassInstanceRef) -> Result { let callbacks: i32 = jvm.get_field(&this, "callbacks", "I").await?; jvm.put_field(&mut this, "callbacks", "I", callbacks + 1).await?; - let size: i32 = jvm.invoke_virtual(&this, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&this, "LimitedLinkedHashMap", "size", "()I", ()).await?; let limit: i32 = jvm.get_field(&this, "limit", "I").await?; Ok(size > limit) @@ -50,11 +50,18 @@ impl LimitedLinkedHashMap { } async fn view_strings(jvm: &Jvm, map: &ClassInstanceRef, method: &str, descriptor: &str) -> Result>> { - let view: ClassInstanceRef = jvm.invoke_virtual(map, method, descriptor, ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&view, "iterator", "()Ljava/util/Iterator;", ()).await?; + let view: ClassInstanceRef = jvm.invoke_virtual(map, &map.class_definition().name(), method, descriptor, ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&view, &view.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let mut values = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; values.push(if value.is_null() { None } else { @@ -66,13 +73,26 @@ async fn view_strings(jvm: &Jvm, map: &ClassInstanceRef, method: &str, d } async fn entry_strings(jvm: &Jvm, map: &ClassInstanceRef) -> Result, Option)>> { - let view: ClassInstanceRef = jvm.invoke_virtual(map, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&view, "iterator", "()Ljava/util/Iterator;", ()).await?; + let view: ClassInstanceRef = jvm + .invoke_virtual(map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&view, &view.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let mut entries = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&entry, "getValue", "()Ljava/lang/Object;", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getValue", "()Ljava/lang/Object;", ()) + .await?; entries.push(( if key.is_null() { None @@ -147,7 +167,13 @@ async fn linked_hash_map_preserves_insertion_order_across_views_nulls_and_rehash let key = JavaLangString::from_rust_string(&jvm, &format!("k{index:02}")).await?; let value = JavaLangString::from_rust_string(&jvm, &format!("v{index:02}")).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } let replacement_key = JavaLangString::from_rust_string(&jvm, "k05").await?; @@ -155,6 +181,7 @@ async fn linked_hash_map_preserves_insertion_order_across_views_nulls_and_rehash let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (replacement_key, replacement), @@ -164,6 +191,7 @@ async fn linked_hash_map_preserves_insertion_order_across_views_nulls_and_rehash let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (null.clone(), null), @@ -181,14 +209,30 @@ async fn linked_hash_map_preserves_insertion_order_across_views_nulls_and_rehash assert_eq!(entries[5], (Some("k05".into()), Some("changed".into()))); assert_eq!(entries.last(), Some(&(None, None))); - let keys: ClassInstanceRef = jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; + let keys: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let key = JavaLangString::from_rust_string(&jvm, "k00").await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)).await?; - let first: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) + .await?; + let first: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &first).await?, "k00"); - let text: ClassInstanceRef = jvm.invoke_virtual(&map, "toString", "()Ljava/lang/String;", ()).await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; let text = JavaLangString::to_rust_string(&jvm, &text).await?; assert!(text.starts_with("{k00=v00, k01=v01, k02=v02")); assert!(text.ends_with(", null=null}")); @@ -204,39 +248,91 @@ async fn linked_hash_map_access_order_tracks_only_documented_accesses() -> Resul let value = JavaLangString::from_rust_string(&jvm, key).await?; let key = JavaLangString::from_rust_string(&jvm, key).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } - let keys: ClassInstanceRef = jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; + let keys: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let tail = JavaLangString::from_rust_string(&jvm, "c").await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (tail,)).await?; - let first: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (tail,), + ) + .await?; + let first: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &first).await?, "a"); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let tail = JavaLangString::from_rust_string(&jvm, "c").await?; let value = JavaLangString::from_rust_string(&jvm, "C").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (tail, value)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (tail, value), + ) + .await?; + let first: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) .await?; - let first: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &first).await?, "a"); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let missing = JavaLangString::from_rust_string(&jvm, "missing").await?; let missing_value: ClassInstanceRef = jvm - .invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (missing,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (missing,), + ) .await?; assert!(missing_value.is_null()); - let first: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let first: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &first).await?, "a"); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let key = JavaLangString::from_rust_string(&jvm, "a").await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key,)).await?; - let result: Result> = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await; + let _: ClassInstanceRef = jvm + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key,), + ) + .await?; + let result: Result> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("access-order get must invalidate an existing iterator"); }; @@ -248,7 +344,7 @@ async fn linked_hash_map_access_order_tracks_only_documented_accesses() -> Resul let key = JavaLangString::from_rust_string(&jvm, "b").await?; assert!( - jvm.invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (key,)) + jvm.invoke_virtual::<_, bool>(&map, &map.class_definition().name(), "containsKey", "(Ljava/lang/Object;)Z", (key,)) .await? ); assert_eq!( @@ -259,7 +355,13 @@ async fn linked_hash_map_access_order_tracks_only_documented_accesses() -> Resul let key = JavaLangString::from_rust_string(&jvm, "b").await?; let value = JavaLangString::from_rust_string(&jvm, "B").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; assert_eq!( view_strings(&jvm, &map, "keySet", "()Ljava/util/Set;").await?, @@ -271,10 +373,18 @@ async fn linked_hash_map_access_order_tracks_only_documented_accesses() -> Resul let value = JavaLangString::from_rust_string(&jvm, key).await?; let key = JavaLangString::from_rust_string(&jvm, key).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&source, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &source, + &source.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } - let _: () = jvm.invoke_virtual(&map, "putAll", "(Ljava/util/Map;)V", (source,)).await?; + let _: () = jvm + .invoke_virtual(&map, &map.class_definition().name(), "putAll", "(Ljava/util/Map;)V", (source,)) + .await?; assert_eq!( view_strings(&jvm, &map, "keySet", "()Ljava/util/Set;").await?, vec![Some("c".into()), Some("b".into()), Some("a".into()), Some("d".into())] @@ -291,58 +401,103 @@ async fn linked_hash_map_views_and_iterators_remove_in_order_and_fail_fast() -> let key = JavaLangString::from_rust_string(&jvm, key).await?; let value = JavaLangString::from_rust_string(&jvm, value).await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } - let values: ClassInstanceRef = jvm.invoke_virtual(&map, "values", "()Ljava/util/Collection;", ()).await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; let same = JavaLangString::from_rust_string(&jvm, "same").await?; - assert!(jvm.invoke_virtual::<_, bool>(&values, "remove", "(Ljava/lang/Object;)Z", (same,)).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&values, &values.class_definition().name(), "remove", "(Ljava/lang/Object;)Z", (same,)) + .await? + ); assert_eq!( view_strings(&jvm, &map, "keySet", "()Ljava/util/Set;").await?, vec![Some("b".into()), Some("c".into())] ); - let keys: ClassInstanceRef = jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; - let first: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let keys: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let first: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &first).await?, "b"); - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; - let result: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; + let result: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("repeated iterator remove must fail"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalStateException")); assert_eq!(view_strings(&jvm, &map, "keySet", "()Ljava/util/Set;").await?, vec![Some("c".into())]); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; let key = JavaLangString::from_rust_string(&jvm, "d").await?; let value = JavaLangString::from_rust_string(&jvm, "other").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; - let result: Result> = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("structural modification must invalidate iterator"); }; assert!(jvm.is_instance(&*exception, "java/util/ConcurrentModificationException")); - let _: () = jvm.invoke_virtual(&map, "clear", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&map, &map.class_definition().name(), "clear", "()V", ()).await?; assert!(view_strings(&jvm, &map, "keySet", "()Ljava/util/Set;").await?.is_empty()); let key = JavaLangString::from_rust_string(&jvm, "reused").await?; let value = JavaLangString::from_rust_string(&jvm, "value").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; assert_eq!( view_strings(&jvm, &map, "keySet", "()Ljava/util/Set;").await?, vec![Some("reused".into())] ); - let keys: ClassInstanceRef = jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let result: Result> = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await; + let keys: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let result: Result> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("exhausted iterator must fail"); }; @@ -369,7 +524,13 @@ async fn linked_hash_map_copy_and_remove_eldest_entry_preserve_policy_and_order( let key = JavaLangString::from_rust_string(&jvm, key).await?; let value = key.clone(); let _: ClassInstanceRef = jvm - .invoke_virtual(&limited, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &limited, + &limited.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; } assert_eq!( @@ -381,7 +542,13 @@ async fn linked_hash_map_copy_and_remove_eldest_entry_preserve_policy_and_order( let key = JavaLangString::from_rust_string(&jvm, "c").await?; let value = JavaLangString::from_rust_string(&jvm, "C").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&limited, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &limited, + &limited.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; assert_eq!(jvm.get_field::(&limited, "callbacks", "I").await?, 3); @@ -392,8 +559,12 @@ async fn linked_hash_map_copy_and_remove_eldest_entry_preserve_policy_and_order( ); assert_eq!(entry_strings(&jvm, ©).await?[1], (Some("c".into()), Some("C".into()))); - let key_set: ClassInstanceRef = jvm.invoke_virtual(©, "keySet", "()Ljava/util/Set;", ()).await?; - let array: ClassInstanceRef> = jvm.invoke_virtual(&key_set, "toArray", "()[Ljava/lang/Object;", ()).await?; + let key_set: ClassInstanceRef = jvm + .invoke_virtual(©, ©.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let array: ClassInstanceRef> = jvm + .invoke_virtual(&key_set, &key_set.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; let keys = jvm.load_array::>(&array, 0, 2).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &keys[0]).await?, "b"); assert_eq!(JavaLangString::to_rust_string(&jvm, &keys[1]).await?, "c"); diff --git a/java_runtime/tests/classes/java/util/test_list_views.rs b/java_runtime/tests/classes/java/util/test_list_views.rs index 477b3a54..b9468239 100644 --- a/java_runtime/tests/classes/java/util/test_list_views.rs +++ b/java_runtime/tests/classes/java/util/test_list_views.rs @@ -12,23 +12,61 @@ async fn list_01_iterators_are_live_and_support_every_state_transition() -> Resu let list = jvm.new_class(class_name, "()V", ()).await?; for value in ["a", "b", "c"] { let value = JavaLangString::from_rust_string(&jvm, value).await?; - let _: bool = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; } - let iterator: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "(I)Ljava/util/ListIterator;", (1,)).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "listIterator", + "(I)Ljava/util/ListIterator;", + (1,), + ) + .await?; assert!(jvm.is_instance(&**iterator, "java/util/ListIterator")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "nextIndex", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "previousIndex", "()I", ()).await?, 0); - - let previous: ClassInstanceRef = jvm.invoke_virtual(&iterator, "previous", "()Ljava/lang/Object;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "nextIndex", "()I", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "previousIndex", "()I", ()) + .await?, + 0 + ); + + let previous: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &previous).await?, "a"); let replacement = JavaLangString::from_rust_string(&jvm, "A").await?; - let _: () = jvm.invoke_virtual(&iterator, "set", "(Ljava/lang/Object;)V", (replacement,)).await?; + let _: () = jvm + .invoke_virtual( + &iterator, + &iterator.class_definition().name(), + "set", + "(Ljava/lang/Object;)V", + (replacement,), + ) + .await?; let inserted = JavaLangString::from_rust_string(&jvm, "x").await?; - let _: () = jvm.invoke_virtual(&iterator, "add", "(Ljava/lang/Object;)V", (inserted,)).await?; + let _: () = jvm + .invoke_virtual( + &iterator, + &iterator.class_definition().name(), + "add", + "(Ljava/lang/Object;)V", + (inserted,), + ) + .await?; - let result: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let result: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("remove after add must fail"); }; @@ -36,6 +74,7 @@ async fn list_01_iterators_are_live_and_support_every_state_transition() -> Resu let result: Result<()> = jvm .invoke_virtual( &iterator, + &iterator.class_definition().name(), "set", "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "invalid").await?,), @@ -46,18 +85,35 @@ async fn list_01_iterators_are_live_and_support_every_state_transition() -> Resu }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalStateException")); - let next: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let next: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &next).await?, "A"); - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; let tail = JavaLangString::from_rust_string(&jvm, "d").await?; - let _: bool = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (tail,)).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let _: bool = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (tail,)) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; } - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "nextIndex", "()I", ()).await?, 4); - - let result: Result> = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "nextIndex", "()I", ()) + .await?, + 4 + ); + + let result: Result> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("exhausted iterator must fail"); }; @@ -65,7 +121,13 @@ async fn list_01_iterators_are_live_and_support_every_state_transition() -> Resu for invalid_index in [-1, 5] { let result: Result> = jvm - .invoke_virtual(&list, "listIterator", "(I)Ljava/util/ListIterator;", (invalid_index,)) + .invoke_virtual( + &list, + &list.class_definition().name(), + "listIterator", + "(I)Ljava/util/ListIterator;", + (invalid_index,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("invalid list iterator index must fail"); @@ -168,22 +230,42 @@ async fn list_01_descriptors_flags_and_iterator_state_fields_match_contract() -> async fn linked_list_list_iterator_covers_boundaries_and_every_legal_transition() -> Result<()> { let jvm = test_jvm().await?; let list = jvm.new_class("java/util/LinkedList", "()V", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "()Ljava/util/ListIterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "listIterator", "()Ljava/util/ListIterator;", ()) + .await?; assert!(jvm.is_instance(&**iterator, "java/util/ListIterator")); assert!(jvm.is_instance(&**iterator, "java/util/Iterator")); - assert!(!jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await?); - assert!(!jvm.invoke_virtual::<_, bool>(&iterator, "hasPrevious", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "nextIndex", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "previousIndex", "()I", ()).await?, -1); + assert!( + !jvm.invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasPrevious", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "nextIndex", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "previousIndex", "()I", ()) + .await?, + -1 + ); for method in ["next", "previous"] { - let result: Result> = jvm.invoke_virtual(&iterator, method, "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), method, "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{method} on an empty iterator must fail"); }; assert!(jvm.is_instance(&*exception, "java/util/NoSuchElementException")); } - let result: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let result: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("remove before traversal must fail"); }; @@ -191,6 +273,7 @@ async fn linked_list_list_iterator_covers_boundaries_and_every_legal_transition( let result: Result<()> = jvm .invoke_virtual( &iterator, + &iterator.class_definition().name(), "set", "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "invalid").await?,), @@ -203,30 +286,55 @@ async fn linked_list_list_iterator_covers_boundaries_and_every_legal_transition( for value in ["a", "b", "c"] { let value = JavaLangString::from_rust_string(&jvm, value).await?; - let _: bool = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; } - let iterator: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "(I)Ljava/util/ListIterator;", (0,)).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "listIterator", + "(I)Ljava/util/ListIterator;", + (0,), + ) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "a"); let _: () = jvm .invoke_virtual( &iterator, + &iterator.class_definition().name(), "set", "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "A").await?,), ) .await?; - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "nextIndex", "()I", ()).await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "previousIndex", "()I", ()).await?, -1); + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "nextIndex", "()I", ()) + .await?, + 0 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "previousIndex", "()I", ()) + .await?, + -1 + ); for method in ["remove", "set"] { let result: Result<()> = if method == "remove" { - jvm.invoke_virtual(&iterator, method, "()V", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), method, "()V", ()) + .await } else { jvm.invoke_virtual( &iterator, + &iterator.class_definition().name(), method, "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "invalid").await?,), @@ -242,19 +350,30 @@ async fn linked_list_list_iterator_covers_boundaries_and_every_legal_transition( let _: () = jvm .invoke_virtual( &iterator, + &iterator.class_definition().name(), "add", "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "x").await?,), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "nextIndex", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "previousIndex", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "nextIndex", "()I", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "previousIndex", "()I", ()) + .await?, + 0 + ); for method in ["remove", "set"] { let result: Result<()> = if method == "remove" { - jvm.invoke_virtual(&iterator, method, "()V", ()).await + jvm.invoke_virtual(&iterator, &iterator.class_definition().name(), method, "()V", ()) + .await } else { jvm.invoke_virtual( &iterator, + &iterator.class_definition().name(), method, "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "invalid").await?,), @@ -267,63 +386,113 @@ async fn linked_list_list_iterator_covers_boundaries_and_every_legal_transition( assert!(jvm.is_instance(&*exception, "java/lang/IllegalStateException")); } - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "previous", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "x"); let _: () = jvm .invoke_virtual( &iterator, + &iterator.class_definition().name(), "set", "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "X").await?,), ) .await?; - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&iterator, "nextIndex", "()I", ()).await?, 0); + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&iterator, &iterator.class_definition().name(), "nextIndex", "()I", ()) + .await?, + 0 + ); - let result: Result> = jvm.invoke_virtual(&iterator, "previous", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("previous at the start boundary must fail"); }; assert!(jvm.is_instance(&*exception, "java/util/NoSuchElementException")); - let middle: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "(I)Ljava/util/ListIterator;", (1,)).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&middle, "previous", "()Ljava/lang/Object;", ()).await?; + let middle: ClassInstanceRef = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "listIterator", + "(I)Ljava/util/ListIterator;", + (1,), + ) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&middle, &middle.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "b"); - let value: ClassInstanceRef = jvm.invoke_virtual(&middle, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&middle, &middle.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "b"); let _: () = jvm .invoke_virtual( &middle, + &middle.class_definition().name(), "set", "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "B").await?,), ) .await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&middle, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&middle, &middle.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "c"); - assert!(!jvm.invoke_virtual::<_, bool>(&middle, "hasNext", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&middle, &middle.class_definition().name(), "hasNext", "()Z", ()) + .await? + ); - let result: Result> = jvm.invoke_virtual(&middle, "next", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&middle, &middle.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("next at the end boundary must fail"); }; assert!(jvm.is_instance(&*exception, "java/util/NoSuchElementException")); - let value: ClassInstanceRef = jvm.invoke_virtual(&middle, "previous", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&middle, &middle.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "c"); - let _: () = jvm.invoke_virtual(&middle, "remove", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&middle, "nextIndex", "()I", ()).await?, 1); - let value: ClassInstanceRef = jvm.invoke_virtual(&middle, "previous", "()Ljava/lang/Object;", ()).await?; + let _: () = jvm + .invoke_virtual(&middle, &middle.class_definition().name(), "remove", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&middle, &middle.class_definition().name(), "nextIndex", "()I", ()) + .await?, + 1 + ); + let value: ClassInstanceRef = jvm + .invoke_virtual(&middle, &middle.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "B"); - let _: () = jvm.invoke_virtual(&middle, "remove", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?, 0); + let _: () = jvm + .invoke_virtual(&middle, &middle.class_definition().name(), "remove", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); let header: ClassInstanceRef = jvm.get_field(&list, "header", "Ljava/util/LinkedList$Entry;").await?; let next: ClassInstanceRef = jvm.get_field(&header, "next", "Ljava/util/LinkedList$Entry;").await?; let previous: ClassInstanceRef = jvm.get_field(&header, "previous", "Ljava/util/LinkedList$Entry;").await?; - assert!(jvm.invoke_virtual::<_, bool>(&header, "equals", "(Ljava/lang/Object;)Z", (next,)).await?); assert!( - jvm.invoke_virtual::<_, bool>(&header, "equals", "(Ljava/lang/Object;)Z", (previous,)) + jvm.invoke_virtual::<_, bool>(&header, &header.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (next,)) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&header, &header.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (previous,)) .await? ); @@ -336,14 +505,24 @@ async fn linked_list_sentinel_unlinks_middle_single_and_last_entries() -> Result let list = jvm.new_class("java/util/LinkedList", "()V", ()).await?; for value in ["first", "middle", "last"] { let value = JavaLangString::from_rust_string(&jvm, value).await?; - let _: bool = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; } - let removed: ClassInstanceRef = jvm.invoke_virtual(&list, "remove", "(I)Ljava/lang/Object;", (1,)).await?; + let removed: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "remove", "(I)Ljava/lang/Object;", (1,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "middle"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); for (index, expected) in ["first", "last"].into_iter().enumerate() { - let value: ClassInstanceRef = jvm.invoke_virtual(&list, "get", "(I)Ljava/lang/Object;", (index as i32,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "get", "(I)Ljava/lang/Object;", (index as i32,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, expected); } @@ -353,31 +532,50 @@ async fn linked_list_sentinel_unlinks_middle_single_and_last_entries() -> Result let first_next: ClassInstanceRef = jvm.get_field(&first, "next", "Ljava/util/LinkedList$Entry;").await?; let last_previous: ClassInstanceRef = jvm.get_field(&last, "previous", "Ljava/util/LinkedList$Entry;").await?; assert!( - jvm.invoke_virtual::<_, bool>(&last, "equals", "(Ljava/lang/Object;)Z", (first_next,)) + jvm.invoke_virtual::<_, bool>(&last, &last.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (first_next,)) .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&first, "equals", "(Ljava/lang/Object;)Z", (last_previous,)) - .await? + jvm.invoke_virtual::<_, bool>( + &first, + &first.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (last_previous,) + ) + .await? ); - let removed: ClassInstanceRef = jvm.invoke_virtual(&list, "removeFirst", "()Ljava/lang/Object;", ()).await?; + let removed: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "removeFirst", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "first"); let header: ClassInstanceRef = jvm.get_field(&list, "header", "Ljava/util/LinkedList$Entry;").await?; let only_next: ClassInstanceRef = jvm.get_field(&header, "next", "Ljava/util/LinkedList$Entry;").await?; let only_previous: ClassInstanceRef = jvm.get_field(&header, "previous", "Ljava/util/LinkedList$Entry;").await?; assert!( - jvm.invoke_virtual::<_, bool>(&only_next, "equals", "(Ljava/lang/Object;)Z", (only_previous,)) - .await? + jvm.invoke_virtual::<_, bool>( + &only_next, + &only_next.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (only_previous,) + ) + .await? ); - let removed: ClassInstanceRef = jvm.invoke_virtual(&list, "removeLast", "()Ljava/lang/Object;", ()).await?; + let removed: ClassInstanceRef = jvm + .invoke_virtual(&list, &list.class_definition().name(), "removeLast", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "last"); let next: ClassInstanceRef = jvm.get_field(&header, "next", "Ljava/util/LinkedList$Entry;").await?; let previous: ClassInstanceRef = jvm.get_field(&header, "previous", "Ljava/util/LinkedList$Entry;").await?; - assert!(jvm.invoke_virtual::<_, bool>(&header, "equals", "(Ljava/lang/Object;)Z", (next,)).await?); assert!( - jvm.invoke_virtual::<_, bool>(&header, "equals", "(Ljava/lang/Object;)Z", (previous,)) + jvm.invoke_virtual::<_, bool>(&header, &header.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (next,)) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&header, &header.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (previous,)) .await? ); @@ -413,13 +611,18 @@ async fn list_02_to_04_linked_list_uses_sentinel_and_live_list_iterator() -> Res let header: ClassInstanceRef = jvm.get_field(&list, "header", "Ljava/util/LinkedList$Entry;").await?; let next: ClassInstanceRef = jvm.get_field(&header, "next", "Ljava/util/LinkedList$Entry;").await?; let previous: ClassInstanceRef = jvm.get_field(&header, "previous", "Ljava/util/LinkedList$Entry;").await?; - assert!(jvm.invoke_virtual::<_, bool>(&header, "equals", "(Ljava/lang/Object;)Z", (next,)).await?); assert!( - jvm.invoke_virtual::<_, bool>(&header, "equals", "(Ljava/lang/Object;)Z", (previous,)) + jvm.invoke_virtual::<_, bool>(&header, &header.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (next,)) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&header, &header.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (previous,)) .await? ); - let result: Result> = jvm.invoke_virtual(&list, "getFirst", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&list, &list.class_definition().name(), "getFirst", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("empty LinkedList.getFirst must fail"); }; @@ -428,22 +631,51 @@ async fn list_02_to_04_linked_list_uses_sentinel_and_live_list_iterator() -> Res let null: ClassInstanceRef = None.into(); let first = JavaLangString::from_rust_string(&jvm, "first").await?; let last = JavaLangString::from_rust_string(&jvm, "last").await?; - let _: () = jvm.invoke_virtual(&list, "addFirst", "(Ljava/lang/Object;)V", (first,)).await?; - let _: bool = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (null,)).await?; - let _: () = jvm.invoke_virtual(&list, "addLast", "(Ljava/lang/Object;)V", (last,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?, 3); + let _: () = jvm + .invoke_virtual(&list, &list.class_definition().name(), "addFirst", "(Ljava/lang/Object;)V", (first,)) + .await?; + let _: bool = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (null,)) + .await?; + let _: () = jvm + .invoke_virtual(&list, &list.class_definition().name(), "addLast", "(Ljava/lang/Object;)V", (last,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await?, + 3 + ); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&list, "listIterator", "(I)Ljava/util/ListIterator;", (3,)).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "previous", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &list, + &list.class_definition().name(), + "listIterator", + "(I)Ljava/util/ListIterator;", + (3,), + ) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "last"); - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&list, "size", "()I", ()).await?, 2); + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&list, &list.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); let duplicate = JavaLangString::from_rust_string(&jvm, "first").await?; - let _: bool = jvm.invoke_virtual(&list, "add", "(Ljava/lang/Object;)Z", (duplicate,)).await?; + let _: bool = jvm + .invoke_virtual(&list, &list.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (duplicate,)) + .await?; assert_eq!( jvm.invoke_virtual::<_, i32>( &list, + &list.class_definition().name(), "indexOf", "(Ljava/lang/Object;)I", (JavaLangString::from_rust_string(&jvm, "first").await?,) @@ -454,6 +686,7 @@ async fn list_02_to_04_linked_list_uses_sentinel_and_live_list_iterator() -> Res assert_eq!( jvm.invoke_virtual::<_, i32>( &list, + &list.class_definition().name(), "lastIndexOf", "(Ljava/lang/Object;)I", (JavaLangString::from_rust_string(&jvm, "first").await?,), @@ -467,17 +700,26 @@ async fn list_02_to_04_linked_list_uses_sentinel_and_live_list_iterator() -> Res .await?; let destination: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/String;", 4).await?.into(); let array: ClassInstanceRef> = jvm - .invoke_virtual(©, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (destination,)) + .invoke_virtual( + ©, + ©.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (destination,), + ) .await?; assert_eq!(jvm.array_length(&array).await?, 4); - let _: () = jvm.invoke_virtual(&list, "clear", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&list, &list.class_definition().name(), "clear", "()V", ()).await?; let header: ClassInstanceRef = jvm.get_field(&list, "header", "Ljava/util/LinkedList$Entry;").await?; let next: ClassInstanceRef = jvm.get_field(&header, "next", "Ljava/util/LinkedList$Entry;").await?; let previous: ClassInstanceRef = jvm.get_field(&header, "previous", "Ljava/util/LinkedList$Entry;").await?; - assert!(jvm.invoke_virtual::<_, bool>(&header, "equals", "(Ljava/lang/Object;)Z", (next,)).await?); assert!( - jvm.invoke_virtual::<_, bool>(&header, "equals", "(Ljava/lang/Object;)Z", (previous,)) + jvm.invoke_virtual::<_, bool>(&header, &header.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (next,)) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&header, &header.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (previous,)) .await? ); @@ -490,30 +732,78 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> let root: ClassInstanceRef = jvm.new_class("java/util/ArrayList", "()V", ()).await?.into(); for value in ["a", "b", "c", "d", "e", "f", "g", "h"] { let value = JavaLangString::from_rust_string(&jvm, value).await?; - let _: bool = jvm.invoke_virtual(&root, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual(&root, &root.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; } - let first: ClassInstanceRef = jvm.invoke_virtual(&root, "subList", "(II)Ljava/util/List;", (1, 7)).await?; - let second: ClassInstanceRef = jvm.invoke_virtual(&first, "subList", "(II)Ljava/util/List;", (1, 5)).await?; - let third: ClassInstanceRef = jvm.invoke_virtual(&second, "subList", "(II)Ljava/util/List;", (1, 3)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 8); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "size", "()I", ()).await?, 6); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "size", "()I", ()).await?, 4); - assert_eq!(jvm.invoke_virtual::<_, i32>(&third, "size", "()I", ()).await?, 2); + let first: ClassInstanceRef = jvm + .invoke_virtual(&root, &root.class_definition().name(), "subList", "(II)Ljava/util/List;", (1, 7)) + .await?; + let second: ClassInstanceRef = jvm + .invoke_virtual(&first, &first.class_definition().name(), "subList", "(II)Ljava/util/List;", (1, 5)) + .await?; + let third: ClassInstanceRef = jvm + .invoke_virtual(&second, &second.class_definition().name(), "subList", "(II)Ljava/util/List;", (1, 3)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 8 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "size", "()I", ()) + .await?, + 6 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, &second.class_definition().name(), "size", "()I", ()) + .await?, + 4 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&third, &third.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); let source = jvm.new_class("java/util/ArrayList", "()V", ()).await?; for value in ["x", "y"] { let value = JavaLangString::from_rust_string(&jvm, value).await?; - let _: bool = jvm.invoke_virtual(&source, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual(&source, &source.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; } assert!( - jvm.invoke_virtual::<_, bool>(&third, "addAll", "(ILjava/util/Collection;)Z", (1, source)) - .await? + jvm.invoke_virtual::<_, bool>( + &third, + &third.class_definition().name(), + "addAll", + "(ILjava/util/Collection;)Z", + (1, source) + ) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 10 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "size", "()I", ()) + .await?, + 8 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, &second.class_definition().name(), "size", "()I", ()) + .await?, + 6 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&third, &third.class_definition().name(), "size", "()I", ()) + .await?, + 4 ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 10); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "size", "()I", ()).await?, 8); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "size", "()I", ()).await?, 6); - assert_eq!(jvm.invoke_virtual::<_, i32>(&third, "size", "()I", ()).await?, 4); for (target, expected) in [ (root.clone(), &["a", "b", "c", "d", "x", "y", "e", "f", "g", "h"][..]), (first.clone(), &["b", "c", "d", "x", "y", "e", "f", "g"][..]), @@ -521,17 +811,43 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> (third.clone(), &["d", "x", "y", "e"][..]), ] { for (index, expected) in expected.iter().enumerate() { - let value: ClassInstanceRef = jvm.invoke_virtual(&target, "get", "(I)Ljava/lang/Object;", (index as i32,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual( + &target, + &target.class_definition().name(), + "get", + "(I)Ljava/lang/Object;", + (index as i32,), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, *expected); } } - let removed: ClassInstanceRef = jvm.invoke_virtual(&third, "remove", "(I)Ljava/lang/Object;", (0,)).await?; + let removed: ClassInstanceRef = jvm + .invoke_virtual(&third, &third.class_definition().name(), "remove", "(I)Ljava/lang/Object;", (0,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "d"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 9); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "size", "()I", ()).await?, 7); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "size", "()I", ()).await?, 5); - assert_eq!(jvm.invoke_virtual::<_, i32>(&third, "size", "()I", ()).await?, 3); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 9 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "size", "()I", ()) + .await?, + 7 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, &second.class_definition().name(), "size", "()I", ()) + .await?, + 5 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&third, &third.class_definition().name(), "size", "()I", ()) + .await?, + 3 + ); for (target, expected) in [ (root.clone(), &["a", "b", "c", "x", "y", "e", "f", "g", "h"][..]), (first.clone(), &["b", "c", "x", "y", "e", "f", "g"][..]), @@ -539,17 +855,36 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> (third.clone(), &["x", "y", "e"][..]), ] { for (index, expected) in expected.iter().enumerate() { - let value: ClassInstanceRef = jvm.invoke_virtual(&target, "get", "(I)Ljava/lang/Object;", (index as i32,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual( + &target, + &target.class_definition().name(), + "get", + "(I)Ljava/lang/Object;", + (index as i32,), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, *expected); } } - let iterator: ClassInstanceRef = jvm.invoke_virtual(&third, "listIterator", "(I)Ljava/util/ListIterator;", (1,)).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &third, + &third.class_definition().name(), + "listIterator", + "(I)Ljava/util/ListIterator;", + (1,), + ) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "y"); let _: () = jvm .invoke_virtual( &iterator, + &iterator.class_definition().name(), "set", "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "Y").await?,), @@ -558,15 +893,32 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> let _: () = jvm .invoke_virtual( &iterator, + &iterator.class_definition().name(), "add", "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "z").await?,), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 10); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "size", "()I", ()).await?, 8); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "size", "()I", ()).await?, 6); - assert_eq!(jvm.invoke_virtual::<_, i32>(&third, "size", "()I", ()).await?, 4); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 10 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "size", "()I", ()) + .await?, + 8 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, &second.class_definition().name(), "size", "()I", ()) + .await?, + 6 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&third, &third.class_definition().name(), "size", "()I", ()) + .await?, + 4 + ); for (target, expected) in [ (root.clone(), &["a", "b", "c", "x", "Y", "z", "e", "f", "g", "h"][..]), (first.clone(), &["b", "c", "x", "Y", "z", "e", "f", "g"][..]), @@ -574,18 +926,46 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> (third.clone(), &["x", "Y", "z", "e"][..]), ] { for (index, expected) in expected.iter().enumerate() { - let value: ClassInstanceRef = jvm.invoke_virtual(&target, "get", "(I)Ljava/lang/Object;", (index as i32,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual( + &target, + &target.class_definition().name(), + "get", + "(I)Ljava/lang/Object;", + (index as i32,), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, *expected); } } - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "previous", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "z"); - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 9); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "size", "()I", ()).await?, 7); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "size", "()I", ()).await?, 5); - assert_eq!(jvm.invoke_virtual::<_, i32>(&third, "size", "()I", ()).await?, 3); + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 9 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "size", "()I", ()) + .await?, + 7 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, &second.class_definition().name(), "size", "()I", ()) + .await?, + 5 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&third, &third.class_definition().name(), "size", "()I", ()) + .await?, + 3 + ); for (target, expected) in [ (root.clone(), &["a", "b", "c", "x", "Y", "e", "f", "g", "h"][..]), (first.clone(), &["b", "c", "x", "Y", "e", "f", "g"][..]), @@ -593,18 +973,46 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> (third.clone(), &["x", "Y", "e"][..]), ] { for (index, expected) in expected.iter().enumerate() { - let value: ClassInstanceRef = jvm.invoke_virtual(&target, "get", "(I)Ljava/lang/Object;", (index as i32,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual( + &target, + &target.class_definition().name(), + "get", + "(I)Ljava/lang/Object;", + (index as i32,), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, *expected); } } - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "previous", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "previous", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "Y"); - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 8); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "size", "()I", ()).await?, 6); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "size", "()I", ()).await?, 4); - assert_eq!(jvm.invoke_virtual::<_, i32>(&third, "size", "()I", ()).await?, 2); + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 8 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "size", "()I", ()) + .await?, + 6 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, &second.class_definition().name(), "size", "()I", ()) + .await?, + 4 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&third, &third.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); for (target, expected) in [ (root.clone(), &["a", "b", "c", "x", "e", "f", "g", "h"][..]), @@ -613,7 +1021,15 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> (third.clone(), &["x", "e"][..]), ] { for (index, expected) in expected.iter().enumerate() { - let value: ClassInstanceRef = jvm.invoke_virtual(&target, "get", "(I)Ljava/lang/Object;", (index as i32,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual( + &target, + &target.class_definition().name(), + "get", + "(I)Ljava/lang/Object;", + (index as i32,), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, *expected); } } @@ -627,7 +1043,13 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> ) .await?; let typed: ClassInstanceRef> = jvm - .invoke_virtual(&third, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (destination,)) + .invoke_virtual( + &third, + &third.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (destination,), + ) .await?; let values: Vec> = jvm.load_array(&typed, 0, 4).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &values[0]).await?, "x"); @@ -635,11 +1057,27 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> assert!(values[2].is_null()); assert_eq!(JavaLangString::to_rust_string(&jvm, &values[3]).await?, "sentinel"); - let _: () = jvm.invoke_virtual(&third, "clear", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 6); - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "size", "()I", ()).await?, 4); - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "size", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&third, "size", "()I", ()).await?, 0); + let _: () = jvm.invoke_virtual(&third, &third.class_definition().name(), "clear", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 6 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "size", "()I", ()) + .await?, + 4 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, &second.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&third, &third.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); for (target, expected) in [ (root.clone(), &["a", "b", "c", "f", "g", "h"][..]), (first.clone(), &["b", "c", "f", "g"][..]), @@ -647,7 +1085,15 @@ async fn nested_sub_lists_propagate_every_mutation_through_three_ancestors() -> (third.clone(), &[] as &[&str]), ] { for (index, expected) in expected.iter().enumerate() { - let value: ClassInstanceRef = jvm.invoke_virtual(&target, "get", "(I)Ljava/lang/Object;", (index as i32,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual( + &target, + &target.class_definition().name(), + "get", + "(I)Ljava/lang/Object;", + (index as i32,), + ) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, *expected); } } @@ -661,51 +1107,149 @@ async fn sl_01_to_02_nested_sub_lists_are_live_in_both_directions() -> Result<() let root = jvm.new_class("java/util/ArrayList", "()V", ()).await?; for value in ["a", "b", "c", "d", "e"] { let value = JavaLangString::from_rust_string(&jvm, value).await?; - let _: bool = jvm.invoke_virtual(&root, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual(&root, &root.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; } - let view: ClassInstanceRef = jvm.invoke_virtual(&root, "subList", "(II)Ljava/util/List;", (1, 5)).await?; - let nested: ClassInstanceRef = jvm.invoke_virtual(&view, "subList", "(II)Ljava/util/List;", (1, 3)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&view, "size", "()I", ()).await?, 4); - assert_eq!(jvm.invoke_virtual::<_, i32>(&nested, "size", "()I", ()).await?, 2); + let view: ClassInstanceRef = jvm + .invoke_virtual(&root, &root.class_definition().name(), "subList", "(II)Ljava/util/List;", (1, 5)) + .await?; + let nested: ClassInstanceRef = jvm + .invoke_virtual(&view, &view.class_definition().name(), "subList", "(II)Ljava/util/List;", (1, 3)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&view, &view.class_definition().name(), "size", "()I", ()) + .await?, + 4 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&nested, &nested.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); let inserted = JavaLangString::from_rust_string(&jvm, "x").await?; - let _: () = jvm.invoke_virtual(&nested, "add", "(ILjava/lang/Object;)V", (1, inserted)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 6); - assert_eq!(jvm.invoke_virtual::<_, i32>(&view, "size", "()I", ()).await?, 5); - assert_eq!(jvm.invoke_virtual::<_, i32>(&nested, "size", "()I", ()).await?, 3); + let _: () = jvm + .invoke_virtual(&nested, &nested.class_definition().name(), "add", "(ILjava/lang/Object;)V", (1, inserted)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 6 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&view, &view.class_definition().name(), "size", "()I", ()) + .await?, + 5 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&nested, &nested.class_definition().name(), "size", "()I", ()) + .await?, + 3 + ); - let root_value: ClassInstanceRef = jvm.invoke_virtual(&root, "get", "(I)Ljava/lang/Object;", (3,)).await?; + let root_value: ClassInstanceRef = jvm + .invoke_virtual(&root, &root.class_definition().name(), "get", "(I)Ljava/lang/Object;", (3,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &root_value).await?, "x"); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&nested, "listIterator", "(I)Ljava/util/ListIterator;", (0,)).await?; - let _: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &nested, + &nested.class_definition().name(), + "listIterator", + "(I)Ljava/util/ListIterator;", + (0,), + ) + .await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let replacement = JavaLangString::from_rust_string(&jvm, "C").await?; - let _: () = jvm.invoke_virtual(&iterator, "set", "(Ljava/lang/Object;)V", (replacement,)).await?; - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; + let _: () = jvm + .invoke_virtual( + &iterator, + &iterator.class_definition().name(), + "set", + "(Ljava/lang/Object;)V", + (replacement,), + ) + .await?; + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 5); - assert_eq!(jvm.invoke_virtual::<_, i32>(&view, "size", "()I", ()).await?, 4); - assert_eq!(jvm.invoke_virtual::<_, i32>(&nested, "size", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 5 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&view, &view.class_definition().name(), "size", "()I", ()) + .await?, + 4 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&nested, &nested.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); - let _: () = jvm.invoke_virtual(&nested, "clear", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 3); - assert_eq!(jvm.invoke_virtual::<_, i32>(&view, "size", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&nested, "size", "()I", ()).await?, 0); + let _: () = jvm.invoke_virtual(&nested, &nested.class_definition().name(), "clear", "()V", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 3 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&view, &view.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&nested, &nested.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); let source = jvm.new_class("java/util/ArrayList", "()V", ()).await?; for value in ["y", "z"] { let value = JavaLangString::from_rust_string(&jvm, value).await?; - let _: bool = jvm.invoke_virtual(&source, "add", "(Ljava/lang/Object;)Z", (value,)).await?; + let _: bool = jvm + .invoke_virtual(&source, &source.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (value,)) + .await?; } - let modified: bool = jvm.invoke_virtual(&view, "addAll", "(ILjava/util/Collection;)Z", (1, source)).await?; + let modified: bool = jvm + .invoke_virtual( + &view, + &view.class_definition().name(), + "addAll", + "(ILjava/util/Collection;)Z", + (1, source), + ) + .await?; assert!(modified); - assert_eq!(jvm.invoke_virtual::<_, i32>(&root, "size", "()I", ()).await?, 5); - assert_eq!(jvm.invoke_virtual::<_, i32>(&view, "size", "()I", ()).await?, 4); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&root, &root.class_definition().name(), "size", "()I", ()) + .await?, + 5 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&view, &view.class_definition().name(), "size", "()I", ()) + .await?, + 4 + ); let typed: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/String;", 0).await?.into(); let typed: ClassInstanceRef> = jvm - .invoke_virtual(&view, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (typed,)) + .invoke_virtual( + &view, + &view.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (typed,), + ) .await?; assert_eq!(jvm.array_length(&typed).await?, 4); @@ -714,7 +1258,9 @@ async fn sl_01_to_02_nested_sub_lists_are_live_in_both_directions() -> Result<() (0, 5, "java/lang/IndexOutOfBoundsException"), (3, 2, "java/lang/IllegalArgumentException"), ] { - let result: Result> = jvm.invoke_virtual(&view, "subList", "(II)Ljava/util/List;", (from, to)).await; + let result: Result> = jvm + .invoke_virtual(&view, &view.class_definition().name(), "subList", "(II)Ljava/util/List;", (from, to)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("invalid subList range must fail"); }; diff --git a/java_runtime/tests/classes/java/util/test_locale.rs b/java_runtime/tests/classes/java/util/test_locale.rs index f4b0aa33..fae03076 100644 --- a/java_runtime/tests/classes/java/util/test_locale.rs +++ b/java_runtime/tests/classes/java/util/test_locale.rs @@ -18,23 +18,37 @@ async fn test_locale_constants_and_accessors() -> Result<()> { let jvm = test_jvm().await?; let english: ClassInstanceRef = jvm.get_static_field("java/util/Locale", "ENGLISH", "Ljava/util/Locale;").await?; - let language = jvm.invoke_virtual(&english, "getLanguage", "()Ljava/lang/String;", ()).await?; + let language = jvm + .invoke_virtual(&english, "java/util/Locale", "getLanguage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &language).await?, "en"); - let country = jvm.invoke_virtual(&english, "getCountry", "()Ljava/lang/String;", ()).await?; + let country = jvm + .invoke_virtual(&english, "java/util/Locale", "getCountry", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &country).await?, ""); - let variant = jvm.invoke_virtual(&english, "getVariant", "()Ljava/lang/String;", ()).await?; + let variant = jvm + .invoke_virtual(&english, "java/util/Locale", "getVariant", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &variant).await?, ""); - let english_string = jvm.invoke_virtual(&english, "toString", "()Ljava/lang/String;", ()).await?; + let english_string = jvm + .invoke_virtual(&english, "java/util/Locale", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &english_string).await?, "en"); let us: ClassInstanceRef = jvm.get_static_field("java/util/Locale", "US", "Ljava/util/Locale;").await?; - let language = jvm.invoke_virtual(&us, "getLanguage", "()Ljava/lang/String;", ()).await?; + let language = jvm + .invoke_virtual(&us, "java/util/Locale", "getLanguage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &language).await?, "en"); - let country = jvm.invoke_virtual(&us, "getCountry", "()Ljava/lang/String;", ()).await?; + let country = jvm + .invoke_virtual(&us, "java/util/Locale", "getCountry", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &country).await?, "US"); - let us_string = jvm.invoke_virtual(&us, "toString", "()Ljava/lang/String;", ()).await?; + let us_string = jvm + .invoke_virtual(&us, "java/util/Locale", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &us_string).await?, "en_US"); Ok(()) @@ -56,21 +70,31 @@ async fn test_locale_constructors_to_string_equals_and_hash_code() -> Result<()> .await? .into(); - let language = jvm.invoke_virtual(&locale, "getLanguage", "()Ljava/lang/String;", ()).await?; + let language = jvm + .invoke_virtual(&locale, "java/util/Locale", "getLanguage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &language).await?, "en"); - let country = jvm.invoke_virtual(&locale, "getCountry", "()Ljava/lang/String;", ()).await?; + let country = jvm + .invoke_virtual(&locale, "java/util/Locale", "getCountry", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &country).await?, "US"); - let variant = jvm.invoke_virtual(&locale, "getVariant", "()Ljava/lang/String;", ()).await?; + let variant = jvm + .invoke_virtual(&locale, "java/util/Locale", "getVariant", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &variant).await?, "POSIX"); - let text = jvm.invoke_virtual(&locale, "toString", "()Ljava/lang/String;", ()).await?; + let text = jvm + .invoke_virtual(&locale, "java/util/Locale", "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "en_US_POSIX"); let same: ClassInstanceRef = jvm .new_class("java/util/Locale", "(Ljava/lang/String;Ljava/lang/String;)V", (en, us)) .await? .into(); - let equals: bool = jvm.invoke_virtual(&locale, "equals", "(Ljava/lang/Object;)Z", (same.clone(),)).await?; + let equals: bool = jvm + .invoke_virtual(&locale, "java/util/Locale", "equals", "(Ljava/lang/Object;)Z", (same.clone(),)) + .await?; assert!(!equals); let same_with_variant: ClassInstanceRef = jvm @@ -86,12 +110,18 @@ async fn test_locale_constructors_to_string_equals_and_hash_code() -> Result<()> .await? .into(); let equals: bool = jvm - .invoke_virtual(&locale, "equals", "(Ljava/lang/Object;)Z", (same_with_variant.clone(),)) + .invoke_virtual( + &locale, + "java/util/Locale", + "equals", + "(Ljava/lang/Object;)Z", + (same_with_variant.clone(),), + ) .await?; assert!(equals); - let hash: i32 = jvm.invoke_virtual(&locale, "hashCode", "()I", ()).await?; - let same_hash: i32 = jvm.invoke_virtual(&same_with_variant, "hashCode", "()I", ()).await?; + let hash: i32 = jvm.invoke_virtual(&locale, "java/util/Locale", "hashCode", "()I", ()).await?; + let same_hash: i32 = jvm.invoke_virtual(&same_with_variant, "java/util/Locale", "hashCode", "()I", ()).await?; assert_eq!(hash, same_hash); Ok(()) @@ -102,9 +132,13 @@ async fn test_locale_default_round_trip_and_null_rejection() -> Result<()> { let jvm = test_jvm().await?; let default: ClassInstanceRef = jvm.invoke_static("java/util/Locale", "getDefault", "()Ljava/util/Locale;", ()).await?; - let language = jvm.invoke_virtual(&default, "getLanguage", "()Ljava/lang/String;", ()).await?; + let language = jvm + .invoke_virtual(&default, "java/util/Locale", "getLanguage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &language).await?, "en"); - let country = jvm.invoke_virtual(&default, "getCountry", "()Ljava/lang/String;", ()).await?; + let country = jvm + .invoke_virtual(&default, "java/util/Locale", "getCountry", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &country).await?, "US"); let custom: ClassInstanceRef = jvm @@ -123,7 +157,9 @@ async fn test_locale_default_round_trip_and_null_rejection() -> Result<()> { .await?; let updated: ClassInstanceRef = jvm.invoke_static("java/util/Locale", "getDefault", "()Ljava/util/Locale;", ()).await?; - let country = jvm.invoke_virtual(&updated, "getCountry", "()Ljava/lang/String;", ()).await?; + let country = jvm + .invoke_virtual(&updated, "java/util/Locale", "getCountry", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &country).await?, "GB"); let err = jvm @@ -148,6 +184,7 @@ async fn test_locale_compatibility_edges() -> Result<()> { let display: Result> = jvm .invoke_virtual( &english, + "java/util/Locale", "getDisplayLanguage", "(Ljava/util/Locale;)Ljava/lang/String;", (ClassInstanceRef::::new(None),), @@ -166,7 +203,8 @@ async fn test_locale_compatibility_edges() -> Result<()> { ) .await? .into(); - let iso3_language = jvm.invoke_virtual::<_, ClassInstanceRef>(&unsupported, "getISO3Language", "()Ljava/lang/String;", ()); + let iso3_language = + jvm.invoke_virtual::<_, ClassInstanceRef>(&unsupported, "java/util/Locale", "getISO3Language", "()Ljava/lang/String;", ()); assert!(matches!(iso3_language.await, Err(JavaError::JavaException(_)))); Ok(()) @@ -192,9 +230,15 @@ async fn test_locale_available_locales_and_iso_lists() -> Result<()> { .load_array::>(&locales, 0, jvm.array_length(&locales).await?) .await? { - let equals_france: bool = jvm.invoke_virtual(&locale, "equals", "(Ljava/lang/Object;)Z", (france.clone(),)).await?; - let equals_germany: bool = jvm.invoke_virtual(&locale, "equals", "(Ljava/lang/Object;)Z", (germany.clone(),)).await?; - let equals_prc: bool = jvm.invoke_virtual(&locale, "equals", "(Ljava/lang/Object;)Z", (prc.clone(),)).await?; + let equals_france: bool = jvm + .invoke_virtual(&locale, "java/util/Locale", "equals", "(Ljava/lang/Object;)Z", (france.clone(),)) + .await?; + let equals_germany: bool = jvm + .invoke_virtual(&locale, "java/util/Locale", "equals", "(Ljava/lang/Object;)Z", (germany.clone(),)) + .await?; + let equals_prc: bool = jvm + .invoke_virtual(&locale, "java/util/Locale", "equals", "(Ljava/lang/Object;)Z", (prc.clone(),)) + .await?; has_france |= equals_france; has_germany |= equals_germany; has_prc |= equals_prc; @@ -224,26 +268,40 @@ async fn test_locale_display_iso3_and_clone_helpers() -> Result<()> { let us: ClassInstanceRef = jvm.get_static_field("java/util/Locale", "US", "Ljava/util/Locale;").await?; - let display_language = jvm.invoke_virtual(&us, "getDisplayLanguage", "()Ljava/lang/String;", ()).await?; + let display_language = jvm + .invoke_virtual(&us, "java/util/Locale", "getDisplayLanguage", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &display_language).await?, "English"); - let display_country = jvm.invoke_virtual(&us, "getDisplayCountry", "()Ljava/lang/String;", ()).await?; + let display_country = jvm + .invoke_virtual(&us, "java/util/Locale", "getDisplayCountry", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &display_country).await?, "United States"); - let display_variant = jvm.invoke_virtual(&us, "getDisplayVariant", "()Ljava/lang/String;", ()).await?; + let display_variant = jvm + .invoke_virtual(&us, "java/util/Locale", "getDisplayVariant", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &display_variant).await?, ""); - let display_name = jvm.invoke_virtual(&us, "getDisplayName", "()Ljava/lang/String;", ()).await?; + let display_name = jvm + .invoke_virtual(&us, "java/util/Locale", "getDisplayName", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &display_name).await?, "English (United States)"); - let iso3_language = jvm.invoke_virtual(&us, "getISO3Language", "()Ljava/lang/String;", ()).await?; + let iso3_language = jvm + .invoke_virtual(&us, "java/util/Locale", "getISO3Language", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &iso3_language).await?, "eng"); - let iso3_country = jvm.invoke_virtual(&us, "getISO3Country", "()Ljava/lang/String;", ()).await?; + let iso3_country = jvm + .invoke_virtual(&us, "java/util/Locale", "getISO3Country", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &iso3_country).await?, "USA"); - let cloned: ClassInstanceRef = jvm.invoke_virtual(&us, "clone", "()Ljava/lang/Object;", ()).await?; - let equals: bool = jvm.invoke_virtual(&us, "equals", "(Ljava/lang/Object;)Z", (cloned,)).await?; + let cloned: ClassInstanceRef = jvm.invoke_virtual(&us, "java/util/Locale", "clone", "()Ljava/lang/Object;", ()).await?; + let equals: bool = jvm + .invoke_virtual(&us, "java/util/Locale", "equals", "(Ljava/lang/Object;)Z", (cloned,)) + .await?; assert!(equals); Ok(()) diff --git a/java_runtime/tests/classes/java/util/test_properties.rs b/java_runtime/tests/classes/java/util/test_properties.rs index 7482c989..b82b5d2b 100644 --- a/java_runtime/tests/classes/java/util/test_properties.rs +++ b/java_runtime/tests/classes/java/util/test_properties.rs @@ -140,6 +140,7 @@ async fn test_properties_inherits_hashtable_map_contract() -> Result<()> { let old: ClassInstanceRef = jvm .invoke_virtual( &properties, + &properties.class_definition().name(), "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;", (key.clone(), value.clone()), @@ -148,7 +149,13 @@ async fn test_properties_inherits_hashtable_map_contract() -> Result<()> { assert!(old.is_null()); let found: ClassInstanceRef = jvm - .invoke_virtual(&properties, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (equal_key,)) + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (equal_key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "value"); @@ -158,6 +165,7 @@ async fn test_properties_inherits_hashtable_map_contract() -> Result<()> { let old: ClassInstanceRef = jvm .invoke_virtual( &properties, + &properties.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (inherited_key, inherited_value), @@ -166,13 +174,23 @@ async fn test_properties_inherits_hashtable_map_contract() -> Result<()> { assert!(old.is_null()); let found: ClassInstanceRef = jvm - .invoke_virtual(&properties, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (inherited_equal_key,)) + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (inherited_equal_key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &found).await?, "map-value"); - let size: i32 = jvm.invoke_virtual(&properties, "size", "()I", ()).await?; + let size: i32 = jvm + .invoke_virtual(&properties, &properties.class_definition().name(), "size", "()I", ()) + .await?; assert_eq!(size, 2); - let key_set: ClassInstanceRef = jvm.invoke_virtual(&properties, "keySet", "()Ljava/util/Set;", ()).await?; + let key_set: ClassInstanceRef = jvm + .invoke_virtual(&properties, &properties.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; assert!(jvm.is_instance(&**key_set, "java/util/Set")); Ok(()) @@ -209,13 +227,20 @@ async fn prop_01_constructors_and_defaults_field() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &actual, + "java/util/Properties", "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;", (key.clone(), value), ) .await?; let inherited: ClassInstanceRef = jvm - .invoke_virtual(&parent, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &parent, + &parent.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &inherited).await?, "yes"); @@ -244,6 +269,7 @@ async fn prop_02_get_property_uses_string_values_and_defaults_chain() -> Result< let _: ClassInstanceRef = jvm .invoke_virtual( properties, + &properties.class_definition().name(), "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;", (key, value), @@ -254,7 +280,13 @@ async fn prop_02_get_property_uses_string_values_and_defaults_chain() -> Result< for (key, expected) in [("root", "root-value"), ("middle", "middle-value"), ("shared", "child-shared")] { let key = JavaLangString::from_rust_string(&jvm, key).await?; let value: ClassInstanceRef = jvm - .invoke_virtual(&child, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &child, + &child.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, expected); } @@ -264,13 +296,20 @@ async fn prop_02_get_property_uses_string_values_and_defaults_chain() -> Result< let _: ClassInstanceRef = jvm .invoke_virtual( &child, + &child.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), non_string), ) .await?; let inherited: ClassInstanceRef = jvm - .invoke_virtual(&child, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &child, + &child.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &inherited).await?, "root-value"); @@ -279,6 +318,7 @@ async fn prop_02_get_property_uses_string_values_and_defaults_chain() -> Result< let value: ClassInstanceRef = jvm .invoke_virtual( &child, + &child.class_definition().name(), "getProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (missing, fallback), @@ -313,7 +353,15 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { jvm.store_array(&mut bytes, 0, source.iter().map(|byte| *byte as i8)).await?; let input: ClassInstanceRef = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (bytes,)).await?.into(); let properties = jvm.new_class("java/util/Properties", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&properties, "load", "(Ljava/io/InputStream;)V", (input,)).await?; + let _: () = jvm + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "load", + "(Ljava/io/InputStream;)V", + (input,), + ) + .await?; for (key, expected) in [ ("continued", "helloworld"), @@ -324,7 +372,13 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { ] { let key = JavaLangString::from_rust_string(&jvm, key).await?; let value: ClassInstanceRef = jvm - .invoke_virtual(&properties, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, expected); } @@ -336,6 +390,7 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &defaults, + "java/util/Properties", "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;", (key, value), @@ -349,16 +404,24 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &child, + &child.class_definition().name(), "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;", (key, value), ) .await?; } - let names: ClassInstanceRef = jvm.invoke_virtual(&child, "propertyNames", "()Ljava/util/Enumeration;", ()).await?; + let names: ClassInstanceRef = jvm + .invoke_virtual(&child, &child.class_definition().name(), "propertyNames", "()Ljava/util/Enumeration;", ()) + .await?; let mut actual_names = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&names, "hasMoreElements", "()Z", ()).await? { - let name: ClassInstanceRef = jvm.invoke_virtual(&names, "nextElement", "()Ljava/lang/Object;", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&names, &names.class_definition().name(), "hasMoreElements", "()Z", ()) + .await? + { + let name: ClassInstanceRef = jvm + .invoke_virtual(&names, &names.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; actual_names.push(JavaLangString::to_rust_string(&jvm, &name).await?); } actual_names.sort(); @@ -368,12 +431,15 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let _: () = jvm .invoke_virtual( &child, + &child.class_definition().name(), "store", "(Ljava/io/OutputStream;Ljava/lang/String;)V", (child_output.clone(), ClassInstanceRef::::from(None)), ) .await?; - let child_bytes: ClassInstanceRef> = jvm.invoke_virtual(&child_output, "toByteArray", "()[B", ()).await?; + let child_bytes: ClassInstanceRef> = jvm + .invoke_virtual(&child_output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; let child_values: Vec = jvm.load_array(&child_bytes, 0, jvm.array_length(&child_bytes).await?).await?; let child_text = RustString::from_utf8(child_values.iter().map(|byte| *byte as u8).collect()).expect("ASCII properties output"); assert!(child_text.contains("local=yes")); @@ -385,12 +451,15 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let _: () = jvm .invoke_virtual( &properties, + &properties.class_definition().name(), "store", "(Ljava/io/OutputStream;Ljava/lang/String;)V", (output.clone(), comments), ) .await?; - let stored: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let stored: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; let stored_values: Vec = jvm.load_array(&stored, 0, jvm.array_length(&stored).await?).await?; let stored_ascii = RustString::from_utf8(stored_values.iter().map(|byte| *byte as u8).collect()).expect("ASCII properties output"); assert!(stored_ascii.contains("#round trip")); @@ -398,10 +467,24 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let input: ClassInstanceRef = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (stored,)).await?.into(); let round_trip = jvm.new_class("java/util/Properties", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&round_trip, "load", "(Ljava/io/InputStream;)V", (input,)).await?; + let _: () = jvm + .invoke_virtual( + &round_trip, + &round_trip.class_definition().name(), + "load", + "(Ljava/io/InputStream;)V", + (input,), + ) + .await?; let latin = JavaLangString::from_rust_string(&jvm, "latin").await?; let value: ClassInstanceRef = jvm - .invoke_virtual(&round_trip, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (latin,)) + .invoke_virtual( + &round_trip, + &round_trip.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (latin,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "é"); @@ -409,14 +492,28 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let mut bytes = jvm.instantiate_array("B", malformed.len()).await?; jvm.store_array(&mut bytes, 0, malformed.iter().map(|byte| *byte as i8)).await?; let input: ClassInstanceRef = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (bytes,)).await?.into(); - let malformed_result: Result<()> = jvm.invoke_virtual(&properties, "load", "(Ljava/io/InputStream;)V", (input,)).await; + let malformed_result: Result<()> = jvm + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "load", + "(Ljava/io/InputStream;)V", + (input,), + ) + .await; let Err(JavaError::JavaException(exception)) = malformed_result else { panic!("malformed unicode escape must throw IllegalArgumentException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalArgumentException")); let broken = JavaLangString::from_rust_string(&jvm, "broken").await?; let broken_value: ClassInstanceRef = jvm - .invoke_virtual(&properties, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (broken,)) + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (broken,), + ) .await?; assert!(broken_value.is_null(), "a malformed logical line must not be committed"); @@ -427,7 +524,13 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let partial_input: ClassInstanceRef = jvm.new_class("FailingAfterInputStream", "([B)V", (partial_bytes,)).await?.into(); let partial_properties = jvm.new_class("java/util/Properties", "()V", ()).await?; let partial_result: Result<()> = jvm - .invoke_virtual(&partial_properties, "load", "(Ljava/io/InputStream;)V", (partial_input,)) + .invoke_virtual( + &partial_properties, + &partial_properties.class_definition().name(), + "load", + "(Ljava/io/InputStream;)V", + (partial_input,), + ) .await; let Err(JavaError::JavaException(exception)) = partial_result else { panic!("an IOException after a complete property must propagate"); @@ -435,7 +538,13 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { assert!(jvm.is_instance(&*exception, "java/io/IOException")); let committed = JavaLangString::from_rust_string(&jvm, "committed").await?; let committed_value: ClassInstanceRef = jvm - .invoke_virtual(&partial_properties, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (committed,)) + .invoke_virtual( + &partial_properties, + &partial_properties.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (committed,), + ) .await?; assert!( !committed_value.is_null(), @@ -446,6 +555,7 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let unfinished_value: ClassInstanceRef = jvm .invoke_virtual( &partial_properties, + &partial_properties.class_definition().name(), "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (unfinished,), @@ -455,7 +565,13 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let failing_input: ClassInstanceRef = jvm.new_class("FailingInputStream", "()V", ()).await?.into(); let failed_load: Result<()> = jvm - .invoke_virtual(&properties, "load", "(Ljava/io/InputStream;)V", (failing_input,)) + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "load", + "(Ljava/io/InputStream;)V", + (failing_input,), + ) .await; let Err(JavaError::JavaException(exception)) = failed_load else { panic!("load IOException must propagate"); @@ -463,7 +579,15 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { assert!(jvm.is_instance(&*exception, "java/io/IOException")); let null_input: ClassInstanceRef = None.into(); - let null_load: Result<()> = jvm.invoke_virtual(&properties, "load", "(Ljava/io/InputStream;)V", (null_input,)).await; + let null_load: Result<()> = jvm + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "load", + "(Ljava/io/InputStream;)V", + (null_input,), + ) + .await; let Err(JavaError::JavaException(exception)) = null_load else { panic!("null input must throw NullPointerException before stream processing"); }; @@ -473,6 +597,7 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { let failed_store: Result<()> = jvm .invoke_virtual( &properties, + &properties.class_definition().name(), "store", "(Ljava/io/OutputStream;Ljava/lang/String;)V", (failing_output, ClassInstanceRef::::from(None)), @@ -493,12 +618,19 @@ async fn prop_03_load_store_property_names_and_failures() -> Result<()> { (string.into(), object.into()) }; let _: ClassInstanceRef = jvm - .invoke_virtual(&invalid, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) + .invoke_virtual( + &invalid, + &invalid.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) .await?; let output: ClassInstanceRef = jvm.new_class("java/io/ByteArrayOutputStream", "()V", ()).await?.into(); let result: Result<()> = jvm .invoke_virtual( &invalid, + &invalid.class_definition().name(), "store", "(Ljava/io/OutputStream;Ljava/lang/String;)V", (output, ClassInstanceRef::::from(None)), @@ -527,11 +659,25 @@ async fn prop_03_eof_backslash_parity_and_incomplete_logical_line() -> Result<() let input = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (bytes,)).await?; let properties = jvm.new_class("java/util/Properties", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&properties, "load", "(Ljava/io/InputStream;)V", (input,)).await?; + let _: () = jvm + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "load", + "(Ljava/io/InputStream;)V", + (input,), + ) + .await?; let key = JavaLangString::from_rust_string(&jvm, key).await?; let value: ClassInstanceRef = jvm - .invoke_virtual(&properties, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &properties, + &properties.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, expected); } @@ -544,14 +690,31 @@ async fn prop_store_and_load_with_substring_key_and_value() -> Result<()> { let jvm = test_jvm().await?; let key_parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let key: ClassInstanceRef = jvm.invoke_virtual(&key_parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let key: ClassInstanceRef = jvm + .invoke_virtual( + &key_parent, + &key_parent.class_definition().name(), + "substring", + "(II)Ljava/lang/String;", + (2, 7), + ) + .await?; let value_parent = JavaLangString::from_rust_string(&jvm, "zzWorldzz").await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&value_parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual( + &value_parent, + &value_parent.class_definition().name(), + "substring", + "(II)Ljava/lang/String;", + (2, 7), + ) + .await?; let properties = jvm.new_class("java/util/Properties", "()V", ()).await?; let _: ClassInstanceRef = jvm .invoke_virtual( &properties, + &properties.class_definition().name(), "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;", (key.clone(), value), @@ -562,22 +725,33 @@ async fn prop_store_and_load_with_substring_key_and_value() -> Result<()> { let _: () = jvm .invoke_virtual( &properties, + &properties.class_definition().name(), "store", "(Ljava/io/OutputStream;Ljava/lang/String;)V", (output.clone(), ClassInstanceRef::::from(None)), ) .await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; let values: Vec = jvm.load_array(&bytes, 0, jvm.array_length(&bytes).await?).await?; let text = RustString::from_utf8(values.iter().map(|byte| *byte as u8).collect()).expect("ASCII properties output"); assert!(text.contains("Hello=World")); let input: ClassInstanceRef = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (bytes,)).await?.into(); let loaded = jvm.new_class("java/util/Properties", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&loaded, "load", "(Ljava/io/InputStream;)V", (input,)).await?; + let _: () = jvm + .invoke_virtual(&loaded, &loaded.class_definition().name(), "load", "(Ljava/io/InputStream;)V", (input,)) + .await?; let result: ClassInstanceRef = jvm - .invoke_virtual(&loaded, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &loaded, + &loaded.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "World"); @@ -589,13 +763,16 @@ async fn prop_empty_substring_key_round_trip() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "HelloWorld").await?; - let empty_key: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (5, 5)).await?; + let empty_key: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (5, 5)) + .await?; let value = JavaLangString::from_rust_string(&jvm, "World").await?; let properties = jvm.new_class("java/util/Properties", "()V", ()).await?; let _: ClassInstanceRef = jvm .invoke_virtual( &properties, + &properties.class_definition().name(), "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;", (empty_key.clone(), value), @@ -606,22 +783,33 @@ async fn prop_empty_substring_key_round_trip() -> Result<()> { let _: () = jvm .invoke_virtual( &properties, + &properties.class_definition().name(), "store", "(Ljava/io/OutputStream;Ljava/lang/String;)V", (output.clone(), ClassInstanceRef::::from(None)), ) .await?; - let bytes: ClassInstanceRef> = jvm.invoke_virtual(&output, "toByteArray", "()[B", ()).await?; + let bytes: ClassInstanceRef> = jvm + .invoke_virtual(&output, "java/io/ByteArrayOutputStream", "toByteArray", "()[B", ()) + .await?; let values: Vec = jvm.load_array(&bytes, 0, jvm.array_length(&bytes).await?).await?; let text = RustString::from_utf8(values.iter().map(|byte| *byte as u8).collect()).unwrap(); assert!(text.contains("=World"), "store output: {text:?}"); let input: ClassInstanceRef = jvm.new_class("java/io/ByteArrayInputStream", "([B)V", (bytes,)).await?.into(); let loaded = jvm.new_class("java/util/Properties", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&loaded, "load", "(Ljava/io/InputStream;)V", (input,)).await?; + let _: () = jvm + .invoke_virtual(&loaded, &loaded.class_definition().name(), "load", "(Ljava/io/InputStream;)V", (input,)) + .await?; let result: ClassInstanceRef = jvm - .invoke_virtual(&loaded, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (empty_key,)) + .invoke_virtual( + &loaded, + &loaded.class_definition().name(), + "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;", + (empty_key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &result).await?, "World"); diff --git a/java_runtime/tests/classes/java/util/test_random.rs b/java_runtime/tests/classes/java/util/test_random.rs index d7697e2b..b39ee012 100644 --- a/java_runtime/tests/classes/java/util/test_random.rs +++ b/java_runtime/tests/classes/java/util/test_random.rs @@ -11,10 +11,14 @@ async fn test_random() -> Result<()> { let seed = 42i64; let random = jvm.new_class("java/util/Random", "(J)V", (seed,)).await?; - let next: i32 = jvm.invoke_virtual(&random, "nextInt", "()I", ()).await?; + let next: i32 = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextInt", "()I", ()) + .await?; assert_eq!(next, -1170105035); - let next: i32 = jvm.invoke_virtual(&random, "nextInt", "()I", ()).await?; + let next: i32 = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextInt", "()I", ()) + .await?; assert_eq!(next, 234785527); Ok(()) @@ -25,20 +29,40 @@ async fn test_random_cldc11_algorithms() -> Result<()> { let jvm = test_jvm().await?; let random = jvm.new_class("java/util/Random", "(J)V", (42i64,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&random, "nextInt", "(I)I", (100,)).await?, 30); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&random, &random.class_definition().name(), "nextInt", "(I)I", (100,)) + .await?, + 30 + ); - let _: () = jvm.invoke_virtual(&random, "setSeed", "(J)V", (42i64,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i64>(&random, "nextLong", "()J", ()).await?, -5025562857975149833); + let _: () = jvm + .invoke_virtual(&random, &random.class_definition().name(), "setSeed", "(J)V", (42i64,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i64>(&random, &random.class_definition().name(), "nextLong", "()J", ()) + .await?, + -5025562857975149833 + ); - let _: () = jvm.invoke_virtual(&random, "setSeed", "(J)V", (42i64,)).await?; - let value: f32 = jvm.invoke_virtual(&random, "nextFloat", "()F", ()).await?; + let _: () = jvm + .invoke_virtual(&random, &random.class_definition().name(), "setSeed", "(J)V", (42i64,)) + .await?; + let value: f32 = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextFloat", "()F", ()) + .await?; assert!((value - 0.7275637).abs() < f32::EPSILON); - let _: () = jvm.invoke_virtual(&random, "setSeed", "(J)V", (42i64,)).await?; - let value: f64 = jvm.invoke_virtual(&random, "nextDouble", "()D", ()).await?; + let _: () = jvm + .invoke_virtual(&random, &random.class_definition().name(), "setSeed", "(J)V", (42i64,)) + .await?; + let value: f64 = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextDouble", "()D", ()) + .await?; assert!((value - 0.7275636800328681).abs() < f64::EPSILON); - let result: Result = jvm.invoke_virtual(&random, "nextInt", "(I)I", (0,)).await; + let result: Result = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextInt", "(I)I", (0,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("non-positive bound must throw IllegalArgumentException"); }; @@ -95,20 +119,45 @@ async fn rng_01_boolean_and_bytes_match_jdk_seed_oracle() -> Result<()> { let jvm = test_jvm().await?; let boolean_random = jvm.new_class("java/util/Random", "(J)V", (42i64,)).await?; - assert!(jvm.invoke_virtual::<_, bool>(&boolean_random, "nextBoolean", "()Z", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&boolean_random, &boolean_random.class_definition().name(), "nextBoolean", "()Z", ()) + .await? + ); let bytes_random = jvm.new_class("java/util/Random", "(J)V", (42i64,)).await?; let mut bytes: ClassInstanceRef> = jvm.instantiate_array("B", 10).await?.into(); - let _: () = jvm.invoke_virtual(&bytes_random, "nextBytes", "([B)V", (bytes.clone(),)).await?; + let _: () = jvm + .invoke_virtual( + &bytes_random, + &bytes_random.class_definition().name(), + "nextBytes", + "([B)V", + (bytes.clone(),), + ) + .await?; assert_eq!( jvm.load_array::(&bytes, 0, 10).await?, vec![53, -99, 65, -70, -9, -118, -2, 13, -31, -69] ); - assert_eq!(jvm.invoke_virtual::<_, i32>(&bytes_random, "nextInt", "()I", ()).await?, 205897768); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&bytes_random, &bytes_random.class_definition().name(), "nextInt", "()I", ()) + .await?, + 205897768 + ); jvm.store_array(&mut bytes, 0, [0i8; 10]).await?; - let _: () = jvm.invoke_virtual(&bytes_random, "setSeed", "(J)V", (42i64,)).await?; - let _: () = jvm.invoke_virtual(&bytes_random, "nextBytes", "([B)V", (bytes.clone(),)).await?; + let _: () = jvm + .invoke_virtual(&bytes_random, &bytes_random.class_definition().name(), "setSeed", "(J)V", (42i64,)) + .await?; + let _: () = jvm + .invoke_virtual( + &bytes_random, + &bytes_random.class_definition().name(), + "nextBytes", + "([B)V", + (bytes.clone(),), + ) + .await?; assert_eq!( jvm.load_array::(&bytes, 0, 10).await?, vec![53, -99, 65, -70, -9, -118, -2, 13, -31, -69] @@ -123,22 +172,44 @@ async fn rng_01_next_bytes_null_and_empty_arrays_do_not_advance_seed() -> Result let random = jvm.new_class("java/util/Random", "(J)V", (42i64,)).await?; let null_bytes: ClassInstanceRef> = None.into(); - let result: Result<()> = jvm.invoke_virtual(&random, "nextBytes", "([B)V", (null_bytes,)).await; + let result: Result<()> = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextBytes", "([B)V", (null_bytes,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("nextBytes(null) must throw NullPointerException"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&random, "nextInt", "()I", ()).await?, -1170105035); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&random, &random.class_definition().name(), "nextInt", "()I", ()) + .await?, + -1170105035 + ); - let _: () = jvm.invoke_virtual(&random, "setSeed", "(J)V", (42i64,)).await?; + let _: () = jvm + .invoke_virtual(&random, &random.class_definition().name(), "setSeed", "(J)V", (42i64,)) + .await?; let empty: ClassInstanceRef> = jvm.instantiate_array("B", 0).await?.into(); - let _: () = jvm.invoke_virtual(&random, "nextBytes", "([B)V", (empty,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&random, "nextInt", "()I", ()).await?, -1170105035); + let _: () = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextBytes", "([B)V", (empty,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&random, &random.class_definition().name(), "nextInt", "()I", ()) + .await?, + -1170105035 + ); - let _: () = jvm.invoke_virtual(&random, "setSeed", "(J)V", (42i64,)).await?; + let _: () = jvm + .invoke_virtual(&random, &random.class_definition().name(), "setSeed", "(J)V", (42i64,)) + .await?; let five: ClassInstanceRef> = jvm.instantiate_array("B", 5).await?.into(); - let _: () = jvm.invoke_virtual(&random, "nextBytes", "([B)V", (five,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&random, "nextInt", "()I", ()).await?, -1360544799); + let _: () = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextBytes", "([B)V", (five,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&random, &random.class_definition().name(), "nextInt", "()I", ()) + .await?, + -1360544799 + ); Ok(()) } @@ -148,21 +219,35 @@ async fn rng_01_gaussian_matches_jdk_seed_oracle_and_consumes_cache() -> Result< let jvm = test_jvm().await?; let random = jvm.new_class("java/util/Random", "(J)V", (42i64,)).await?; - let first: f64 = jvm.invoke_virtual(&random, "nextGaussian", "()D", ()).await?; + let first: f64 = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextGaussian", "()D", ()) + .await?; assert!((first - 1.1419053154730547).abs() < 1e-15); assert!(jvm.get_field::(&random, "haveNextNextGaussian", "Z").await?); let cached: f64 = jvm.get_field(&random, "nextNextGaussian", "D").await?; - let second: f64 = jvm.invoke_virtual(&random, "nextGaussian", "()D", ()).await?; + let second: f64 = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextGaussian", "()D", ()) + .await?; assert_eq!(second.to_bits(), cached.to_bits()); assert!((second - 0.9194079489827879).abs() < 1e-15); assert!(!jvm.get_field::(&random, "haveNextNextGaussian", "Z").await?); - let after_cached: i32 = jvm.invoke_virtual(&random, "nextInt", "()I", ()).await?; + let after_cached: i32 = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextInt", "()I", ()) + .await?; let control = jvm.new_class("java/util/Random", "(J)V", (42i64,)).await?; - let _: f64 = jvm.invoke_virtual(&control, "nextDouble", "()D", ()).await?; - let _: f64 = jvm.invoke_virtual(&control, "nextDouble", "()D", ()).await?; - assert_eq!(after_cached, jvm.invoke_virtual::<_, i32>(&control, "nextInt", "()I", ()).await?); + let _: f64 = jvm + .invoke_virtual(&control, &control.class_definition().name(), "nextDouble", "()D", ()) + .await?; + let _: f64 = jvm + .invoke_virtual(&control, &control.class_definition().name(), "nextDouble", "()D", ()) + .await?; + assert_eq!( + after_cached, + jvm.invoke_virtual::<_, i32>(&control, &control.class_definition().name(), "nextInt", "()I", ()) + .await? + ); Ok(()) } @@ -172,12 +257,18 @@ async fn rng_02_set_seed_clears_gaussian_cache() -> Result<()> { let jvm = test_jvm().await?; let random = jvm.new_class("java/util/Random", "(J)V", (42i64,)).await?; - let first: f64 = jvm.invoke_virtual(&random, "nextGaussian", "()D", ()).await?; + let first: f64 = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextGaussian", "()D", ()) + .await?; assert!(jvm.get_field::(&random, "haveNextNextGaussian", "Z").await?); - let _: () = jvm.invoke_virtual(&random, "setSeed", "(J)V", (42i64,)).await?; + let _: () = jvm + .invoke_virtual(&random, &random.class_definition().name(), "setSeed", "(J)V", (42i64,)) + .await?; assert!(!jvm.get_field::(&random, "haveNextNextGaussian", "Z").await?); - let reset_first: f64 = jvm.invoke_virtual(&random, "nextGaussian", "()D", ()).await?; + let reset_first: f64 = jvm + .invoke_virtual(&random, &random.class_definition().name(), "nextGaussian", "()D", ()) + .await?; assert_eq!(reset_first.to_bits(), first.to_bits()); Ok(()) diff --git a/java_runtime/tests/classes/java/util/test_stack.rs b/java_runtime/tests/classes/java/util/test_stack.rs index 05b3ca58..1ff13fef 100644 --- a/java_runtime/tests/classes/java/util/test_stack.rs +++ b/java_runtime/tests/classes/java/util/test_stack.rs @@ -13,19 +13,35 @@ async fn test_stack_push_pop() -> Result<()> { let element2 = JavaLangString::from_rust_string(&jvm, "testValue2").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;", (element1.clone(),)) + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "push", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (element1.clone(),), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;", (element2.clone(),)) + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "push", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (element2.clone(),), + ) .await?; - let size: i32 = jvm.invoke_virtual(&stack, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&stack, &stack.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 2); - let popped: ClassInstanceRef = jvm.invoke_virtual(&stack, "pop", "()Ljava/lang/Object;", ()).await?; + let popped: ClassInstanceRef = jvm + .invoke_virtual(&stack, &stack.class_definition().name(), "pop", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &popped).await?, "testValue2"); - let popped: ClassInstanceRef = jvm.invoke_virtual(&stack, "pop", "()Ljava/lang/Object;", ()).await?; + let popped: ClassInstanceRef = jvm + .invoke_virtual(&stack, &stack.class_definition().name(), "pop", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &popped).await?, "testValue1"); Ok(()) @@ -41,19 +57,35 @@ async fn test_stack_peek() -> Result<()> { let element2 = JavaLangString::from_rust_string(&jvm, "testValue2").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;", (element1.clone(),)) + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "push", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (element1.clone(),), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;", (element2.clone(),)) + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "push", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (element2.clone(),), + ) .await?; - let size: i32 = jvm.invoke_virtual(&stack, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&stack, &stack.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 2); - let peek: ClassInstanceRef = jvm.invoke_virtual(&stack, "peek", "()Ljava/lang/Object;", ()).await?; + let peek: ClassInstanceRef = jvm + .invoke_virtual(&stack, &stack.class_definition().name(), "peek", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &peek).await?, "testValue2"); - let peek: ClassInstanceRef = jvm.invoke_virtual(&stack, "pop", "()Ljava/lang/Object;", ()).await?; + let peek: ClassInstanceRef = jvm + .invoke_virtual(&stack, &stack.class_definition().name(), "pop", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &peek).await?, "testValue2"); Ok(()) @@ -72,31 +104,87 @@ async fn test_stack_search() -> Result<()> { let element5 = JavaLangString::from_rust_string(&jvm, "testValue4").await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;", (element1.clone(),)) + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "push", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (element1.clone(),), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;", (element2.clone(),)) + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "push", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (element2.clone(),), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;", (element3.clone(),)) + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "push", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (element3.clone(),), + ) .await?; let _: ClassInstanceRef = jvm - .invoke_virtual(&stack, "push", "(Ljava/lang/Object;)Ljava/lang/Object;", (element1.clone(),)) + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "push", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (element1.clone(),), + ) .await?; - let size: i32 = jvm.invoke_virtual(&stack, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&stack, &stack.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 4); - let peek: i32 = jvm.invoke_virtual(&stack, "search", "(Ljava/lang/Object;)I", (element2.clone(),)).await?; + let peek: i32 = jvm + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "search", + "(Ljava/lang/Object;)I", + (element2.clone(),), + ) + .await?; assert_eq!(peek, 3); - let peek: i32 = jvm.invoke_virtual(&stack, "search", "(Ljava/lang/Object;)I", (element1.clone(),)).await?; + let peek: i32 = jvm + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "search", + "(Ljava/lang/Object;)I", + (element1.clone(),), + ) + .await?; assert_eq!(peek, 1); - let peek: i32 = jvm.invoke_virtual(&stack, "search", "(Ljava/lang/Object;)I", (element4.clone(),)).await?; + let peek: i32 = jvm + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "search", + "(Ljava/lang/Object;)I", + (element4.clone(),), + ) + .await?; assert_eq!(peek, 2); - let peek: i32 = jvm.invoke_virtual(&stack, "search", "(Ljava/lang/Object;)I", (element5.clone(),)).await?; + let peek: i32 = jvm + .invoke_virtual( + &stack, + &stack.class_definition().name(), + "search", + "(Ljava/lang/Object;)I", + (element5.clone(),), + ) + .await?; assert_eq!(peek, -1); Ok(()) diff --git a/java_runtime/tests/classes/java/util/test_string_tokenizer.rs b/java_runtime/tests/classes/java/util/test_string_tokenizer.rs index 413cb02f..a5cd0579 100644 --- a/java_runtime/tests/classes/java/util/test_string_tokenizer.rs +++ b/java_runtime/tests/classes/java/util/test_string_tokenizer.rs @@ -62,9 +62,15 @@ async fn tok_01_constructors_and_utf16_delimiters() -> Result<()> { let input = JavaLangString::from_rust_string(&jvm, " one\t two\nthree ").await?; let tokenizer = jvm.new_class("java/util/StringTokenizer", "(Ljava/lang/String;)V", (input,)).await?; assert_eq!(jvm.get_field::(&tokenizer, "maxPosition", "I").await?, 16); - assert_eq!(jvm.invoke_virtual::<_, i32>(&tokenizer, "countTokens", "()I", ()).await?, 3); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&tokenizer, &tokenizer.class_definition().name(), "countTokens", "()I", ()) + .await?, + 3 + ); for expected in ["one", "two", "three"] { - let token: ClassInstanceRef = jvm.invoke_virtual(&tokenizer, "nextToken", "()Ljava/lang/String;", ()).await?; + let token: ClassInstanceRef = jvm + .invoke_virtual(&tokenizer, &tokenizer.class_definition().name(), "nextToken", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &token).await?, expected); } @@ -87,12 +93,27 @@ async fn tok_01_constructors_and_utf16_delimiters() -> Result<()> { ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&tokenizer, "countTokens", "()I", ()).await?, 5); - let first: ClassInstanceRef = jvm.invoke_virtual(&tokenizer, "nextToken", "()Ljava/lang/String;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&tokenizer, &tokenizer.class_definition().name(), "countTokens", "()I", ()) + .await?, + 5 + ); + let first: ClassInstanceRef = jvm + .invoke_virtual(&tokenizer, &tokenizer.class_definition().name(), "nextToken", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &first).await?, "a"); - let delimiter: ClassInstanceRef = jvm.invoke_virtual(&tokenizer, "nextToken", "()Ljava/lang/String;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&delimiter, "length", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, JavaChar>(&delimiter, "charAt", "(I)C", (0,)).await?, 0xD800); + let delimiter: ClassInstanceRef = jvm + .invoke_virtual(&tokenizer, &tokenizer.class_definition().name(), "nextToken", "()Ljava/lang/String;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&delimiter, "java/lang/String", "length", "()I", ()).await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, JavaChar>(&delimiter, "java/lang/String", "charAt", "(I)C", (0,)) + .await?, + 0xD800 + ); let null_input: ClassInstanceRef = None.into(); let result = jvm.new_class("java/util/StringTokenizer", "(Ljava/lang/String;)V", (null_input,)).await; @@ -113,26 +134,61 @@ async fn tok_02_token_api_enumeration_and_delimiter_change() -> Result<()> { .new_class("java/util/StringTokenizer", "(Ljava/lang/String;Ljava/lang/String;)V", (input, comma)) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&tokenizer, "hasMoreTokens", "()Z", ()).await?); - assert!(jvm.invoke_virtual::<_, bool>(&tokenizer, "hasMoreElements", "()Z", ()).await?); - assert_eq!(jvm.invoke_virtual::<_, i32>(&tokenizer, "countTokens", "()I", ()).await?, 2); + assert!( + jvm.invoke_virtual::<_, bool>(&tokenizer, &tokenizer.class_definition().name(), "hasMoreTokens", "()Z", ()) + .await? + ); + assert!( + jvm.invoke_virtual::<_, bool>(&tokenizer, &tokenizer.class_definition().name(), "hasMoreElements", "()Z", ()) + .await? + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&tokenizer, &tokenizer.class_definition().name(), "countTokens", "()I", ()) + .await?, + 2 + ); - let first: ClassInstanceRef = jvm.invoke_virtual(&tokenizer, "nextToken", "()Ljava/lang/String;", ()).await?; + let first: ClassInstanceRef = jvm + .invoke_virtual(&tokenizer, &tokenizer.class_definition().name(), "nextToken", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &first).await?, "a"); let semicolon = JavaLangString::from_rust_string(&jvm, ";").await?; let second: ClassInstanceRef = jvm - .invoke_virtual(&tokenizer, "nextToken", "(Ljava/lang/String;)Ljava/lang/String;", (semicolon,)) + .invoke_virtual( + &tokenizer, + &tokenizer.class_definition().name(), + "nextToken", + "(Ljava/lang/String;)Ljava/lang/String;", + (semicolon,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &second).await?, ",b"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&tokenizer, "countTokens", "()I", ()).await?, 1); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&tokenizer, &tokenizer.class_definition().name(), "countTokens", "()I", ()) + .await?, + 1 + ); - let last: ClassInstanceRef = jvm.invoke_virtual(&tokenizer, "nextElement", "()Ljava/lang/Object;", ()).await?; + let last: ClassInstanceRef = jvm + .invoke_virtual( + &tokenizer, + &tokenizer.class_definition().name(), + "nextElement", + "()Ljava/lang/Object;", + (), + ) + .await?; assert!(jvm.is_instance(&**last, "java/lang/String")); assert_eq!(JavaLangString::to_rust_string(&jvm, &last).await?, "c"); - assert!(!jvm.invoke_virtual::<_, bool>(&tokenizer, "hasMoreTokens", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&tokenizer, &tokenizer.class_definition().name(), "hasMoreTokens", "()Z", ()) + .await? + ); - let exhausted: Result> = jvm.invoke_virtual(&tokenizer, "nextToken", "()Ljava/lang/String;", ()).await; + let exhausted: Result> = jvm + .invoke_virtual(&tokenizer, &tokenizer.class_definition().name(), "nextToken", "()Ljava/lang/String;", ()) + .await; let Err(JavaError::JavaException(exception)) = exhausted else { panic!("exhausted tokenizer must throw NoSuchElementException"); }; @@ -148,8 +204,19 @@ async fn tok_02_token_api_enumeration_and_delimiter_change() -> Result<()> { ) .await?; let mut tokens = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&tokenizer, "hasMoreElements", "()Z", ()).await? { - let token: ClassInstanceRef = jvm.invoke_virtual(&tokenizer, "nextElement", "()Ljava/lang/Object;", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&tokenizer, &tokenizer.class_definition().name(), "hasMoreElements", "()Z", ()) + .await? + { + let token: ClassInstanceRef = jvm + .invoke_virtual( + &tokenizer, + &tokenizer.class_definition().name(), + "nextElement", + "()Ljava/lang/Object;", + (), + ) + .await?; tokens.push(JavaLangString::to_rust_string(&jvm, &token).await?); } assert_eq!(tokens, ["a", ",", ",", "b"]); @@ -167,7 +234,9 @@ async fn tok_03_next_token_shares_input_value() -> Result<()> { let input_value: ClassInstanceRef> = jvm.get_field(&input, "value", "[C").await?; for (expected, offset) in [("one", 1), ("two", 5)] { - let token: ClassInstanceRef = jvm.invoke_virtual(&tokenizer, "nextToken", "()Ljava/lang/String;", ()).await?; + let token: ClassInstanceRef = jvm + .invoke_virtual(&tokenizer, &tokenizer.class_definition().name(), "nextToken", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &token).await?, expected); let token_value: ClassInstanceRef> = jvm.get_field(&token, "value", "[C").await?; @@ -183,7 +252,9 @@ async fn tok_03_next_token_shares_input_value() -> Result<()> { async fn tok_04_substring_input_composes_offsets_and_shares_root_value() -> Result<()> { let jvm = test_jvm().await?; let root = JavaLangString::from_rust_string(&jvm, "xx one two yy").await?; - let input: ClassInstanceRef = jvm.invoke_virtual(&root, "substring", "(II)Ljava/lang/String;", (3, 10)).await?; + let input: ClassInstanceRef = jvm + .invoke_virtual(&root, &root.class_definition().name(), "substring", "(II)Ljava/lang/String;", (3, 10)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &input).await?, "one two"); let root_value: ClassInstanceRef> = jvm.get_field(&root, "value", "[C").await?; @@ -192,9 +263,15 @@ async fn tok_04_substring_input_composes_offsets_and_shares_root_value() -> Resu .new_class("java/util/StringTokenizer", "(Ljava/lang/String;)V", (input.clone(),)) .await?; assert_eq!(jvm.get_field::(&tokenizer, "maxPosition", "I").await?, 7); - assert_eq!(jvm.invoke_virtual::<_, i32>(&tokenizer, "countTokens", "()I", ()).await?, 2); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&tokenizer, &tokenizer.class_definition().name(), "countTokens", "()I", ()) + .await?, + 2 + ); for (expected, offset) in [("one", 3), ("two", 7)] { - let token: ClassInstanceRef = jvm.invoke_virtual(&tokenizer, "nextToken", "()Ljava/lang/String;", ()).await?; + let token: ClassInstanceRef = jvm + .invoke_virtual(&tokenizer, &tokenizer.class_definition().name(), "nextToken", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &token).await?, expected); let token_value: ClassInstanceRef> = jvm.get_field(&token, "value", "[C").await?; @@ -202,7 +279,10 @@ async fn tok_04_substring_input_composes_offsets_and_shares_root_value() -> Resu assert_eq!(jvm.get_field::(&token, "offset", "I").await?, offset); assert_eq!(jvm.get_field::(&token, "count", "I").await?, 3); } - assert!(!jvm.invoke_virtual::<_, bool>(&tokenizer, "hasMoreTokens", "()Z", ()).await?); + assert!( + !jvm.invoke_virtual::<_, bool>(&tokenizer, &tokenizer.class_definition().name(), "hasMoreTokens", "()Z", ()) + .await? + ); let space = JavaLangString::from_rust_string(&jvm, " ").await?; let tokenizer = jvm @@ -212,10 +292,19 @@ async fn tok_04_substring_input_composes_offsets_and_shares_root_value() -> Resu (input, space, true), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&tokenizer, "countTokens", "()I", ()).await?, 3); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&tokenizer, &tokenizer.class_definition().name(), "countTokens", "()I", ()) + .await?, + 3 + ); let mut tokens = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&tokenizer, "hasMoreTokens", "()Z", ()).await? { - let token: ClassInstanceRef = jvm.invoke_virtual(&tokenizer, "nextToken", "()Ljava/lang/String;", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&tokenizer, &tokenizer.class_definition().name(), "hasMoreTokens", "()Z", ()) + .await? + { + let token: ClassInstanceRef = jvm + .invoke_virtual(&tokenizer, &tokenizer.class_definition().name(), "nextToken", "()Ljava/lang/String;", ()) + .await?; tokens.push(JavaLangString::to_rust_string(&jvm, &token).await?); } assert_eq!(tokens, ["one", " ", "two"]); diff --git a/java_runtime/tests/classes/java/util/test_timer.rs b/java_runtime/tests/classes/java/util/test_timer.rs index 88e481b6..e00cdb0d 100644 --- a/java_runtime/tests/classes/java/util/test_timer.rs +++ b/java_runtime/tests/classes/java/util/test_timer.rs @@ -47,7 +47,7 @@ impl TestTimerTask { jvm.monitor_enter(&this).await?; let update_result = async { let run_count: i32 = jvm.get_field(&this, "runCount", "I").await?; - let scheduled_time: i64 = jvm.invoke_virtual(&this, "scheduledExecutionTime", "()J", ()).await?; + let scheduled_time: i64 = jvm.invoke_virtual(&this, "TestTimerTask", "scheduledExecutionTime", "()J", ()).await?; let actual_time = context.now() as i64; if run_count == 0 { jvm.put_field(&mut this, "firstScheduledTime", "J", scheduled_time).await?; @@ -226,11 +226,15 @@ async fn timer_01_to_05_registers_jdk_shaped_api_and_state() -> Result<()> { let (runtime, jvm) = timer_test_jvm(1_000).await?; let instance: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); assert_eq!(jvm.get_field::(&instance, "state", "I").await?, 0); - assert!(!jvm.invoke_virtual::<_, bool>(&instance, "cancel", "()Z", ()).await?); + assert!(!jvm.invoke_virtual::<_, bool>(&instance, "TestTimerTask", "cancel", "()Z", ()).await?); assert_eq!(jvm.get_field::(&instance, "state", "I").await?, 3); - assert_eq!(jvm.invoke_virtual::<_, i64>(&instance, "scheduledExecutionTime", "()J", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&instance, "TestTimerTask", "scheduledExecutionTime", "()J", ()) + .await?, + 0 + ); let timer = jvm.new_class("java/util/Timer", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(next_spawn(&runtime).await, "cancelled timer worker").await?; Ok(()) } @@ -243,35 +247,65 @@ async fn timer_validation_happens_before_task_mutation() -> Result<()> { let null_task: ClassInstanceRef = None.into(); assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (null_task, -1i64)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (null_task, -1i64), + ) + .await, "java/lang/NullPointerException", ) .await; assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (task.clone(), -1i64)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (task.clone(), -1i64), + ) + .await, "java/lang/IllegalArgumentException", ) .await; assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (task.clone(), 10i64)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (task.clone(), 10i64), + ) + .await, "java/lang/IllegalArgumentException", ) .await; for method in ["schedule", "scheduleAtFixedRate"] { assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, method, "(Ljava/util/TimerTask;JJ)V", (task.clone(), 10i64, 1i64)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + method, + "(Ljava/util/TimerTask;JJ)V", + (task.clone(), 10i64, 1i64), + ) + .await, "java/lang/IllegalArgumentException", ) .await; } for method in ["schedule", "scheduleAtFixedRate"] { assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, method, "(Ljava/util/TimerTask;JJ)V", (task.clone(), 0i64, 0i64)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + method, + "(Ljava/util/TimerTask;JJ)V", + (task.clone(), 0i64, 0i64), + ) + .await, "java/lang/IllegalArgumentException", ) .await; @@ -281,6 +315,7 @@ async fn timer_validation_happens_before_task_mutation() -> Result<()> { assert_exception( jvm.invoke_virtual::<_, ()>( &timer, + &timer.class_definition().name(), "schedule", "(Ljava/util/TimerTask;Ljava/util/Date;)V", (task.clone(), negative_date), @@ -291,8 +326,14 @@ async fn timer_validation_happens_before_task_mutation() -> Result<()> { .await; let null_date: ClassInstanceRef = None.into(); assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, "schedule", "(Ljava/util/TimerTask;Ljava/util/Date;)V", (task.clone(), null_date)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;Ljava/util/Date;)V", + (task.clone(), null_date), + ) + .await, "java/lang/NullPointerException", ) .await; @@ -300,10 +341,16 @@ async fn timer_validation_happens_before_task_mutation() -> Result<()> { assert_eq!(jvm.get_field::(&task, "nextExecutionTime", "J").await?, 0); assert_eq!(jvm.get_field::(&task, "period", "J").await?, 0); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (task.clone(), 0i64)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (task.clone(), 0i64), + ) + .await, "java/lang/IllegalStateException", ) .await; @@ -319,11 +366,18 @@ async fn timer_normalizes_long_max_period_and_rejects_first_recurrence_overflow( let fixed_delay: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let fixed_rate: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let _: () = jvm - .invoke_virtual(&timer, "schedule", "(Ljava/util/TimerTask;JJ)V", (fixed_delay.clone(), 0i64, i64::MAX)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;JJ)V", + (fixed_delay.clone(), 0i64, i64::MAX), + ) .await?; let _: () = jvm .invoke_virtual( &timer, + &timer.class_definition().name(), "scheduleAtFixedRate", "(Ljava/util/TimerTask;JJ)V", (fixed_rate.clone(), 0i64, i64::MAX), @@ -331,7 +385,7 @@ async fn timer_normalizes_long_max_period_and_rejects_first_recurrence_overflow( .await?; assert_eq!(jvm.get_field::(&fixed_delay, "period", "J").await?, (-i64::MAX) >> 1); assert_eq!(jvm.get_field::(&fixed_rate, "period", "J").await?, i64::MAX >> 1); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(next_spawn(&runtime).await, "large-period timer worker").await?; let (runtime, jvm) = timer_test_jvm(i64::MAX as u64 - 100).await?; @@ -339,8 +393,14 @@ async fn timer_normalizes_long_max_period_and_rejects_first_recurrence_overflow( for method in ["schedule", "scheduleAtFixedRate"] { let task: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, method, "(Ljava/util/TimerTask;JJ)V", (task.clone(), 0i64, 101i64)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + method, + "(Ljava/util/TimerTask;JJ)V", + (task.clone(), 0i64, 101i64), + ) + .await, "java/lang/IllegalArgumentException", ) .await; @@ -352,6 +412,7 @@ async fn timer_normalizes_long_max_period_and_rejects_first_recurrence_overflow( assert_exception( jvm.invoke_virtual::<_, ()>( &timer, + &timer.class_definition().name(), "schedule", "(Ljava/util/TimerTask;Ljava/util/Date;J)V", (dated.clone(), date, 60i64), @@ -361,7 +422,7 @@ async fn timer_normalizes_long_max_period_and_rejects_first_recurrence_overflow( ) .await; assert_eq!(jvm.get_field::(&dated, "state", "I").await?, 0); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(next_spawn(&runtime).await, "near-boundary validation timer worker").await?; Ok(()) } @@ -374,6 +435,7 @@ async fn timer_worker_stops_periodic_tasks_when_next_deadline_overflows() -> Res let _: () = jvm .invoke_virtual( &timer, + &timer.class_definition().name(), "scheduleAtFixedRate", "(Ljava/util/TimerTask;JJ)V", (fixed_rate.clone(), 0i64, 60i64), @@ -402,14 +464,20 @@ async fn timer_worker_stops_periodic_tasks_when_next_deadline_overflows() -> Res let thread: ClassInstanceRef = jvm.get_field(&timer, "thread", "Ljava/util/Timer$TimerThread;").await?; let queue: ClassInstanceRef = jvm.get_field(&thread, "queue", "Ljava/util/Timer$TaskQueue;").await?; assert_eq!(jvm.get_field::(&queue, "size", "I").await?, 0); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(worker, "near-boundary fixed-rate timer worker").await?; let (runtime, jvm) = timer_test_jvm(i64::MAX as u64 - 100).await?; let timer = jvm.new_class("java/util/Timer", "()V", ()).await?; let fixed_delay: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let _: () = jvm - .invoke_virtual(&timer, "schedule", "(Ljava/util/TimerTask;JJ)V", (fixed_delay.clone(), 0i64, 60i64)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;JJ)V", + (fixed_delay.clone(), 0i64, 60i64), + ) .await?; runtime.advance_time(Duration::from_millis(50)); let notification = prepare_task_notification(&jvm, &fixed_delay).await?; @@ -417,7 +485,7 @@ async fn timer_worker_stops_periodic_tasks_when_next_deadline_overflows() -> Res wait_for_task_notification(&jvm, &fixed_delay, notification).await?; assert_eq!(jvm.get_field::(&fixed_delay, "runCount", "I").await?, 1); assert_eq!(jvm.get_field::(&fixed_delay, "state", "I").await?, 2); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(worker, "near-boundary fixed-delay timer worker").await?; Ok(()) } @@ -429,10 +497,22 @@ async fn timer_uses_min_heap_and_rejects_task_reuse() -> Result<()> { let later: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let earlier: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let _: () = jvm - .invoke_virtual(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (later.clone(), 200i64)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (later.clone(), 200i64), + ) .await?; let _: () = jvm - .invoke_virtual(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (earlier.clone(), 100i64)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (earlier.clone(), 100i64), + ) .await?; let thread: ClassInstanceRef = jvm.get_field(&timer, "thread", "Ljava/util/Timer$TimerThread;").await?; @@ -443,14 +523,20 @@ async fn timer_uses_min_heap_and_rejects_task_reuse() -> Result<()> { assert_eq!(first.identity(), earlier.identity()); assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (earlier.clone(), 0i64)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (earlier.clone(), 0i64), + ) + .await, "java/lang/IllegalStateException", ) .await; - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; assert_eq!(jvm.get_field::(&queue, "size", "I").await?, 0); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(next_spawn(&runtime).await, "heap timer worker").await?; Ok(()) } @@ -461,7 +547,13 @@ async fn timer_one_shot_executes_once_and_records_scheduled_time() -> Result<()> let timer = jvm.new_class("java/util/Timer", "()V", ()).await?; let task: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let _: () = jvm - .invoke_virtual(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (task.clone(), 100i64)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (task.clone(), 100i64), + ) .await?; let notification = prepare_task_notification(&jvm, &task).await?; @@ -481,11 +573,15 @@ async fn timer_one_shot_executes_once_and_records_scheduled_time() -> Result<()> assert_eq!(jvm.get_field::(&task, "state", "I").await?, 2); assert_eq!(jvm.get_field::(&task, "firstScheduledTime", "J").await?, 1_100); assert_eq!(jvm.get_field::(&task, "firstActualTime", "J").await?, 1_100); - assert_eq!(jvm.invoke_virtual::<_, i64>(&task, "scheduledExecutionTime", "()J", ()).await?, 1_100); - assert!(!jvm.invoke_virtual::<_, bool>(&task, "cancel", "()Z", ()).await?); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&task, "TestTimerTask", "scheduledExecutionTime", "()J", ()) + .await?, + 1_100 + ); + assert!(!jvm.invoke_virtual::<_, bool>(&task, "TestTimerTask", "cancel", "()Z", ()).await?); assert_eq!(jvm.get_field::(&task, "state", "I").await?, 3); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(worker, "one-shot timer worker").await?; Ok(()) } @@ -497,7 +593,13 @@ async fn timer_new_first_task_wakes_worker_and_recomputes_deadline() -> Result<( let later: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let earlier: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let _: () = jvm - .invoke_virtual(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (later.clone(), 200i64)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (later.clone(), 200i64), + ) .await?; let mut worker = next_spawn(&runtime).await; @@ -510,7 +612,13 @@ async fn timer_new_first_task_wakes_worker_and_recomputes_deadline() -> Result<( ); let notification = prepare_task_notification(&jvm, &earlier).await?; let _: () = jvm - .invoke_virtual(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (earlier.clone(), 100i64)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (earlier.clone(), 100i64), + ) .await?; let new_timeout = next_spawn_while_worker_runs(&runtime, &mut worker).await; tokio::time::timeout(TEST_BARRIER_TIMEOUT, runtime.wait_for_sleep_deadline(1_100)) @@ -528,7 +636,7 @@ async fn timer_new_first_task_wakes_worker_and_recomputes_deadline() -> Result<( .expect("timed out waiting for later timeout callback") .expect("later timeout"); drop(stale_later_timeout); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(worker, "new-first timer worker").await?; runtime.advance_time(Duration::from_millis(100)); await_spawn(old_timeout, "stale timeout callback").await?; @@ -541,17 +649,27 @@ async fn timer_task_cancel_only_reports_a_live_schedule() -> Result<()> { let timer = jvm.new_class("java/util/Timer", "()V", ()).await?; let task: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let _: () = jvm - .invoke_virtual(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (task.clone(), 100i64)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (task.clone(), 100i64), + ) .await?; - assert!(jvm.invoke_virtual::<_, bool>(&task, "cancel", "()Z", ()).await?); - assert!(!jvm.invoke_virtual::<_, bool>(&task, "cancel", "()Z", ()).await?); + assert!(jvm.invoke_virtual::<_, bool>(&task, "TestTimerTask", "cancel", "()Z", ()).await?); + assert!(!jvm.invoke_virtual::<_, bool>(&task, "TestTimerTask", "cancel", "()Z", ()).await?); assert_eq!(jvm.get_field::(&task, "state", "I").await?, 3); let worker = next_spawn(&runtime).await; - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(worker, "cancelled-task timer worker").await?; assert_eq!(jvm.get_field::(&task, "runCount", "I").await?, 0); - assert_eq!(jvm.invoke_virtual::<_, i64>(&task, "scheduledExecutionTime", "()J", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i64>(&task, "TestTimerTask", "scheduledExecutionTime", "()J", ()) + .await?, + 0 + ); Ok(()) } @@ -561,7 +679,13 @@ async fn timer_fixed_delay_uses_actual_execution_time() -> Result<()> { let timer = jvm.new_class("java/util/Timer", "()V", ()).await?; let task: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let _: () = jvm - .invoke_virtual(&timer, "schedule", "(Ljava/util/TimerTask;JJ)V", (task.clone(), 100i64, 50i64)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;JJ)V", + (task.clone(), 100i64, 50i64), + ) .await?; assert_eq!(jvm.get_field::(&task, "period", "J").await?, -50); @@ -593,7 +717,7 @@ async fn timer_fixed_delay_uses_actual_execution_time() -> Result<()> { assert_eq!(jvm.get_field::(&task, "nextExecutionTime", "J").await?, 1_250); drop(next_timeout); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(worker, "fixed-delay timer worker").await?; Ok(()) } @@ -604,7 +728,13 @@ async fn timer_fixed_rate_catches_up_from_previous_deadline() -> Result<()> { let timer = jvm.new_class("java/util/Timer", "()V", ()).await?; let task: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); let _: () = jvm - .invoke_virtual(&timer, "scheduleAtFixedRate", "(Ljava/util/TimerTask;JJ)V", (task.clone(), 100i64, 50i64)) + .invoke_virtual( + &timer, + &timer.class_definition().name(), + "scheduleAtFixedRate", + "(Ljava/util/TimerTask;JJ)V", + (task.clone(), 100i64, 50i64), + ) .await?; assert_eq!(jvm.get_field::(&task, "period", "J").await?, 50); @@ -635,7 +765,7 @@ async fn timer_fixed_rate_catches_up_from_previous_deadline() -> Result<()> { assert_eq!(jvm.get_field::(&task, "nextExecutionTime", "J").await?, 1_250); drop(next_timeout); - let _: () = jvm.invoke_virtual(&timer, "cancel", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&timer, &timer.class_definition().name(), "cancel", "()V", ()).await?; await_spawn(worker, "fixed-rate timer worker").await?; Ok(()) } @@ -649,6 +779,7 @@ async fn timer_date_schedule_and_task_exception_close_worker() -> Result<()> { let _: () = jvm .invoke_virtual( &timer, + &timer.class_definition().name(), "schedule", "(Ljava/util/TimerTask;Ljava/util/Date;J)V", (task.clone(), date, 25i64), @@ -671,8 +802,14 @@ async fn timer_date_schedule_and_task_exception_close_worker() -> Result<()> { let fresh: ClassInstanceRef = jvm.new_class("TestTimerTask", "()V", ()).await?.into(); assert_exception( - jvm.invoke_virtual::<_, ()>(&timer, "schedule", "(Ljava/util/TimerTask;J)V", (fresh.clone(), 0i64)) - .await, + jvm.invoke_virtual::<_, ()>( + &timer, + &timer.class_definition().name(), + "schedule", + "(Ljava/util/TimerTask;J)V", + (fresh.clone(), 0i64), + ) + .await, "java/lang/IllegalStateException", ) .await; diff --git a/java_runtime/tests/classes/java/util/test_timezone.rs b/java_runtime/tests/classes/java/util/test_timezone.rs index 6cf4a4ae..18119c6c 100644 --- a/java_runtime/tests/classes/java/util/test_timezone.rs +++ b/java_runtime/tests/classes/java/util/test_timezone.rs @@ -18,15 +18,26 @@ async fn test_timezone() -> Result<()> { assert!(!timezone.is_null()); - let id: ClassInstanceRef = jvm.invoke_virtual(&timezone, "getID", "()Ljava/lang/String;", ()).await?; + let id: ClassInstanceRef = jvm + .invoke_virtual(&timezone, "java/util/TimeZone", "getID", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &id).await?, "UTC"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&timezone, "getRawOffset", "()I", ()).await?, 0); - assert!(!jvm.invoke_virtual::<_, bool>(&timezone, "useDaylightTime", "()Z", ()).await?); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&timezone, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?, + 0 + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&timezone, "java/util/TimeZone", "useDaylightTime", "()Z", ()) + .await? + ); let default: ClassInstanceRef = jvm .invoke_static("java/util/TimeZone", "getDefault", "()Ljava/util/TimeZone;", ()) .await?; - let id: ClassInstanceRef = jvm.invoke_virtual(&default, "getID", "()Ljava/lang/String;", ()).await?; + let id: ClassInstanceRef = jvm + .invoke_virtual(&default, "java/util/TimeZone", "getID", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &id).await?, "GMT"); let ids: ClassInstanceRef> = jvm @@ -50,7 +61,9 @@ async fn test_timezone() -> Result<()> { (unknown,), ) .await?; - let id: ClassInstanceRef = jvm.invoke_virtual(&fallback, "getID", "()Ljava/lang/String;", ()).await?; + let id: ClassInstanceRef = jvm + .invoke_virtual(&fallback, "java/util/TimeZone", "getID", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &id).await?, "GMT"); Ok(()) @@ -64,15 +77,19 @@ async fn test_simple_timezone_constructors_and_offset_validation() -> Result<()> let timezone = jvm .new_class("java/util/SimpleTimeZone", "(ILjava/lang/String;)V", (3_600_000, id)) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&timezone, "getRawOffset", "()I", ()).await?, 3_600_000); assert_eq!( - jvm.invoke_virtual::<_, i32>(&timezone, "getOffset", "(IIIIII)I", (1, 2026, 0, 1, 1, 0)) + jvm.invoke_virtual::<_, i32>(&timezone, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?, + 3_600_000 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&timezone, "java/util/TimeZone", "getOffset", "(IIIIII)I", (1, 2026, 0, 1, 1, 0)) .await?, 3_600_000 ); for (year, month, day) in [(2024, 1, 29), (2000, 1, 29), (2026, 3, 30), (2026, 11, 31)] { assert_eq!( - jvm.invoke_virtual::<_, i32>(&timezone, "getOffset", "(IIIIII)I", (1, year, month, day, 1, 0)) + jvm.invoke_virtual::<_, i32>(&timezone, "java/util/TimeZone", "getOffset", "(IIIIII)I", (1, year, month, day, 1, 0)) .await?, 3_600_000 ); @@ -89,19 +106,30 @@ async fn test_simple_timezone_constructors_and_offset_validation() -> Result<()> (1, 2026, 10, 31), ] { let invalid: Result = jvm - .invoke_virtual(&timezone, "getOffset", "(IIIIII)I", (era, year, month, day, 1, 0)) + .invoke_virtual(&timezone, "java/util/TimeZone", "getOffset", "(IIIIII)I", (era, year, month, day, 1, 0)) .await; let Err(JavaError::JavaException(exception)) = invalid else { panic!("invalid calendar fields must throw IllegalArgumentException"); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalArgumentException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&timezone, "getRawOffset", "()I", ()).await?, 3_600_000); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&timezone, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?, + 3_600_000 + ); } let id = JavaLangString::from_rust_string(&jvm, "Legacy").await?; let legacy = jvm.new_class("java/util/SimpleTimeZone", "(Ljava/lang/String;)V", (id,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&legacy, "getRawOffset", "()I", ()).await?, 0); - assert!(!jvm.invoke_virtual::<_, bool>(&legacy, "useDaylightTime", "()Z", ()).await?); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&legacy, &legacy.class_definition().name(), "getRawOffset", "()I", ()) + .await?, + 0 + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&legacy, &legacy.class_definition().name(), "useDaylightTime", "()Z", ()) + .await? + ); let null_id: ClassInstanceRef = None.into(); let result = jvm.new_class("java/util/SimpleTimeZone", "(ILjava/lang/String;)V", (0, null_id)).await; @@ -145,22 +173,38 @@ async fn tz_01_default_is_cloned_on_set_and_get_and_null_resets_gmt() -> Result< .invoke_static("java/util/TimeZone", "setDefault", "(Ljava/util/TimeZone;)V", (configured.clone(),)) .await?; - let _: () = jvm.invoke_virtual(&configured, "setRawOffset", "(I)V", (7_200_000,)).await?; + let _: () = jvm + .invoke_virtual(&configured, "java/util/TimeZone", "setRawOffset", "(I)V", (7_200_000,)) + .await?; let changed = JavaLangString::from_rust_string(&jvm, "Changed").await?; - let _: () = jvm.invoke_virtual(&configured, "setID", "(Ljava/lang/String;)V", (changed,)).await?; + let _: () = jvm + .invoke_virtual(&configured, "java/util/TimeZone", "setID", "(Ljava/lang/String;)V", (changed,)) + .await?; let first: ClassInstanceRef = jvm .invoke_static("java/util/TimeZone", "getDefault", "()Ljava/util/TimeZone;", ()) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "getRawOffset", "()I", ()).await?, 3_600_000); - let first_id: ClassInstanceRef = jvm.invoke_virtual(&first, "getID", "()Ljava/lang/String;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?, + 3_600_000 + ); + let first_id: ClassInstanceRef = jvm + .invoke_virtual(&first, "java/util/TimeZone", "getID", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &first_id).await?, "Custom"); - let _: () = jvm.invoke_virtual(&first, "setRawOffset", "(I)V", (10_800_000,)).await?; + let _: () = jvm + .invoke_virtual(&first, "java/util/TimeZone", "setRawOffset", "(I)V", (10_800_000,)) + .await?; let second: ClassInstanceRef = jvm .invoke_static("java/util/TimeZone", "getDefault", "()Ljava/util/TimeZone;", ()) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&second, "getRawOffset", "()I", ()).await?, 3_600_000); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&second, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?, + 3_600_000 + ); let null: ClassInstanceRef = None.into(); let _: () = jvm @@ -169,9 +213,15 @@ async fn tz_01_default_is_cloned_on_set_and_get_and_null_resets_gmt() -> Result< let reset: ClassInstanceRef = jvm .invoke_static("java/util/TimeZone", "getDefault", "()Ljava/util/TimeZone;", ()) .await?; - let id: ClassInstanceRef = jvm.invoke_virtual(&reset, "getID", "()Ljava/lang/String;", ()).await?; + let id: ClassInstanceRef = jvm + .invoke_virtual(&reset, "java/util/TimeZone", "getID", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &id).await?, "GMT"); - assert_eq!(jvm.invoke_virtual::<_, i32>(&reset, "getRawOffset", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&reset, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?, + 0 + ); Ok(()) } @@ -208,34 +258,55 @@ async fn tz_02_to_04_id_abstract_contract_and_simple_timezone_mutation() -> Resu let id = JavaLangString::from_rust_string(&jvm, "Initial").await?; let timezone = jvm.new_class("java/util/SimpleTimeZone", "(ILjava/lang/String;)V", (1_000, id)).await?; let changed = JavaLangString::from_rust_string(&jvm, "Changed").await?; - let _: () = jvm.invoke_virtual(&timezone, "setID", "(Ljava/lang/String;)V", (changed,)).await?; - let id: ClassInstanceRef = jvm.invoke_virtual(&timezone, "getID", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&timezone, "java/util/TimeZone", "setID", "(Ljava/lang/String;)V", (changed,)) + .await?; + let id: ClassInstanceRef = jvm + .invoke_virtual(&timezone, "java/util/TimeZone", "getID", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &id).await?, "Changed"); - let _: () = jvm.invoke_virtual(&timezone, "setRawOffset", "(I)V", (-2_000,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&timezone, "getRawOffset", "()I", ()).await?, -2_000); + let _: () = jvm + .invoke_virtual(&timezone, "java/util/TimeZone", "setRawOffset", "(I)V", (-2_000,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&timezone, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?, + -2_000 + ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&timezone, "getOffset", "(IIIIII)I", (1, 2026, 0, 1, 1, 0)) + jvm.invoke_virtual::<_, i32>(&timezone, "java/util/TimeZone", "getOffset", "(IIIIII)I", (1, 2026, 0, 1, 1, 0)) .await?, -2_000 ); let date = jvm.new_class("java/util/Date", "(J)V", (0i64,)).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&timezone, "inDaylightTime", "(Ljava/util/Date;)Z", (date,)) + !jvm.invoke_virtual::<_, bool>(&timezone, "java/util/TimeZone", "inDaylightTime", "(Ljava/util/Date;)Z", (date,)) + .await? + ); + assert!( + !jvm.invoke_virtual::<_, bool>(&timezone, "java/util/TimeZone", "useDaylightTime", "()Z", ()) .await? ); - assert!(!jvm.invoke_virtual::<_, bool>(&timezone, "useDaylightTime", "()Z", ()).await?); let null_date: ClassInstanceRef = None.into(); - let result: Result = jvm.invoke_virtual(&timezone, "inDaylightTime", "(Ljava/util/Date;)Z", (null_date,)).await; + let result: Result = jvm + .invoke_virtual(&timezone, "java/util/TimeZone", "inDaylightTime", "(Ljava/util/Date;)Z", (null_date,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("null Date must throw NullPointerException"); }; assert!(jvm.is_instance(&*exception, "java/lang/NullPointerException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&timezone, "getRawOffset", "()I", ()).await?, -2_000); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&timezone, "java/util/TimeZone", "getRawOffset", "()I", ()) + .await?, + -2_000 + ); let null_id: ClassInstanceRef = None.into(); - let result: Result<()> = jvm.invoke_virtual(&timezone, "setID", "(Ljava/lang/String;)V", (null_id,)).await; + let result: Result<()> = jvm + .invoke_virtual(&timezone, "java/util/TimeZone", "setID", "(Ljava/lang/String;)V", (null_id,)) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("null ID must throw NullPointerException"); }; diff --git a/java_runtime/tests/classes/java/util/test_tree_map.rs b/java_runtime/tests/classes/java/util/test_tree_map.rs index 19a83557..6c918ade 100644 --- a/java_runtime/tests/classes/java/util/test_tree_map.rs +++ b/java_runtime/tests/classes/java/util/test_tree_map.rs @@ -79,8 +79,10 @@ impl TreeTestComparator { if !jvm.is_instance(left.as_ref(), "java/lang/Integer") || !jvm.is_instance(right.as_ref(), "java/lang/Integer") { return Err(jvm.exception("java/lang/ClassCastException", "integer keys required").await); } - let mut left_value: i32 = jvm.invoke_virtual(&left, "intValue", "()I", ()).await?; - let mut right_value: i32 = jvm.invoke_virtual(&right, "intValue", "()I", ()).await?; + let mut left_value: i32 = jvm.invoke_virtual(&left, &left.class_definition().name(), "intValue", "()I", ()).await?; + let mut right_value: i32 = jvm + .invoke_virtual(&right, &right.class_definition().name(), "intValue", "()I", ()) + .await?; if jvm.get_field::(&this, "absolute", "Z").await? { left_value = left_value.saturating_abs(); right_value = right_value.saturating_abs(); @@ -399,24 +401,40 @@ async fn put_integer(jvm: &Jvm, map: &ClassInstanceRef, key: i32, value: Some(value) => integer(jvm, value).await?, None => None.into(), }; - jvm.invoke_virtual(map, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, value)) - .await + jvm.invoke_virtual( + map, + &map.class_definition().name(), + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + (key, value), + ) + .await } async fn ordered_integer_keys(jvm: &Jvm, map: &ClassInstanceRef) -> Result> { - let keys: ClassInstanceRef = jvm.invoke_virtual(map, "keySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&keys, "iterator", "()Ljava/util/Iterator;", ()).await?; - let expected_size: i32 = jvm.invoke_virtual(map, "size", "()I", ()).await?; + let keys: ClassInstanceRef = jvm + .invoke_virtual(map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&keys, &keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let expected_size: i32 = jvm.invoke_virtual(map, &map.class_definition().name(), "size", "()I", ()).await?; let mut result = Vec::with_capacity(expected_size as usize); for _ in 0..expected_size { - if !jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { + if !jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { break; } - let key: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - result.push(jvm.invoke_virtual(&key, "intValue", "()I", ()).await?); + let key: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + result.push(jvm.invoke_virtual(&key, &key.class_definition().name(), "intValue", "()I", ()).await?); } assert!( - !jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await?, + !jvm.invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?, "TreeMap iterator exceeded map size, indicating a cycle or duplicate traversal" ); Ok(result) @@ -424,7 +442,7 @@ async fn ordered_integer_keys(jvm: &Jvm, map: &ClassInstanceRef) -> Resu async fn assert_red_black_invariants(jvm: &Jvm, map: &ClassInstanceRef) -> Result<()> { let root: ClassInstanceRef = jvm.get_field(map, "root", "Ljava/util/TreeMap$Entry;").await?; - let expected_size: i32 = jvm.invoke_virtual(map, "size", "()I", ()).await?; + let expected_size: i32 = jvm.invoke_virtual(map, &map.class_definition().name(), "size", "()I", ()).await?; if root.is_null() { assert_eq!(expected_size, 0); return Ok(()); @@ -439,7 +457,7 @@ async fn assert_red_black_invariants(jvm: &Jvm, map: &ClassInstanceRef) while let Some((node, lower, upper, black_count)) = stack.pop() { assert!(seen.insert(node.identity()), "tree must not contain a cycle"); let key: ClassInstanceRef = jvm.get_field(&node, "key", "Ljava/lang/Object;").await?; - let key: i32 = jvm.invoke_virtual(&key, "intValue", "()I", ()).await?; + let key: i32 = jvm.invoke_virtual(&key, &key.class_definition().name(), "intValue", "()I", ()).await?; assert!(lower.is_none_or(|lower| key > lower)); assert!(upper.is_none_or(|upper| key < upper)); let black = jvm.get_field::(&node, "color", "Z").await?; @@ -743,14 +761,24 @@ async fn tm_02_tm_03_red_black_invariants_hold_for_deterministic_insert_delete_p } for key in deletion_order { let removed: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, key).await?,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (integer(&jvm, key).await?,), + ) .await?; assert!(!removed.is_null()); expected.remove(&key); assert_red_black_invariants(&jvm, &map).await?; assert_eq!(ordered_integer_keys(&jvm, &map).await?, expected.iter().copied().collect::>()); } - assert_eq!(jvm.invoke_virtual::<_, i32>(&map, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&map, &map.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); } Ok(()) } @@ -786,7 +814,13 @@ async fn tm_02_tm_03_red_black_invariants_hold_for_seeded_randomized_mutations() } for key in deletion_order { let removed: ClassInstanceRef = jvm - .invoke_virtual(&map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, key).await?,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (integer(&jvm, key).await?,), + ) .await?; assert!(!removed.is_null()); expected.remove(&key); @@ -804,7 +838,9 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { let map: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "()V", ()).await?.into(); for method in ["firstKey", "lastKey"] { - let result: Result> = jvm.invoke_virtual(&map, method, "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&map, &map.class_definition().name(), method, "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("empty TreeMap.{method} must throw"); }; @@ -812,7 +848,13 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { } let null_result: Result = jvm - .invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (ClassInstanceRef::::from(None),)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (ClassInstanceRef::::from(None),), + ) .await; let Err(JavaError::JavaException(exception)) = null_result else { panic!("natural-order null query must throw"); @@ -821,7 +863,13 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { let plain_object: ClassInstanceRef = jvm.new_class("java/lang/Object", "()V", ()).await?.into(); let non_comparable: Result = jvm - .invoke_virtual(&map, "containsKey", "(Ljava/lang/Object;)Z", (plain_object.clone(),)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (plain_object.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = non_comparable else { panic!("natural-order non-comparable query must throw"); @@ -833,6 +881,7 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { let failing_put: Result> = jvm .invoke_virtual( &failing_map, + &failing_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (failing_key, integer(&jvm, 1).await?), @@ -842,7 +891,11 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { panic!("first natural-order put must compare key with itself"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/IllegalStateException")); - assert_eq!(jvm.invoke_virtual::<_, i32>(&failing_map, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&failing_map, &failing_map.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); let stored: ClassInstanceRef = jvm.new_class("TreeDirectionalKey", "(IZ)V", (7, false)).await?.into(); let stored_for_mutation = stored.clone(); @@ -850,6 +903,7 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (stored, value.clone()), @@ -859,7 +913,13 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { jvm.put_field(&mut stored_for_mutation, "fail", "Z", true).await?; let query: ClassInstanceRef = jvm.new_class("TreeDirectionalKey", "(IZ)V", (7, false)).await?.into(); let found: ClassInstanceRef = jvm - .invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (query,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (query,), + ) .await?; assert_eq!(found.identity(), value.identity(), "lookup must call query.compareTo(stored)"); @@ -869,12 +929,19 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&reverse_map, "containsKey", "(Ljava/lang/Object;)Z", (plain_object.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &reverse_map, + &reverse_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (plain_object.clone(),) + ) + .await? ); let invalid_first_put: Result> = jvm .invoke_virtual( &reverse_map, + &reverse_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (plain_object, integer(&jvm, 1).await?), @@ -888,7 +955,15 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { put_integer(&jvm, &reverse_map, key, Some(key)).await?; } assert_eq!(ordered_integer_keys(&jvm, &reverse_map).await?, vec![3, 2, 1]); - let comparator: ClassInstanceRef = jvm.invoke_virtual(&reverse_map, "comparator", "()Ljava/util/Comparator;", ()).await?; + let comparator: ClassInstanceRef = jvm + .invoke_virtual( + &reverse_map, + &reverse_map.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + (), + ) + .await?; assert_eq!(comparator.identity(), reverse.identity()); let nulls_first: ClassInstanceRef = jvm.new_class("TreeTestComparator", "(ZZZ)V", (false, true, false)).await?.into(); @@ -899,6 +974,7 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &null_map, + &null_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (ClassInstanceRef::::from(None), integer(&jvm, 9).await?), @@ -908,23 +984,46 @@ async fn tm_02_tm_03_natural_and_custom_comparator_contracts() -> Result<()> { assert!( jvm.invoke_virtual::<_, bool>( &null_map, + &null_map.class_definition().name(), "containsKey", "(Ljava/lang/Object;)Z", (ClassInstanceRef::::from(None),) ) .await? ); - let first: ClassInstanceRef = jvm.invoke_virtual(&null_map, "firstKey", "()Ljava/lang/Object;", ()).await?; + let first: ClassInstanceRef = jvm + .invoke_virtual(&null_map, &null_map.class_definition().name(), "firstKey", "()Ljava/lang/Object;", ()) + .await?; assert!(first.is_null()); let absolute: ClassInstanceRef = jvm.new_class("TreeTestComparator", "(ZZZ)V", (false, false, true)).await?.into(); let equivalent_map: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "(Ljava/util/Comparator;)V", (absolute,)).await?.into(); assert!(put_integer(&jvm, &equivalent_map, -4, Some(1)).await?.is_null()); let replaced = put_integer(&jvm, &equivalent_map, 4, Some(2)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&replaced, "intValue", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&equivalent_map, "size", "()I", ()).await?, 1); - let key: ClassInstanceRef = jvm.invoke_virtual(&equivalent_map, "firstKey", "()Ljava/lang/Object;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&key, "intValue", "()I", ()).await?, -4); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&replaced, &replaced.class_definition().name(), "intValue", "()I", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&equivalent_map, &equivalent_map.class_definition().name(), "size", "()I", ()) + .await?, + 1 + ); + let key: ClassInstanceRef = jvm + .invoke_virtual( + &equivalent_map, + &equivalent_map.class_definition().name(), + "firstKey", + "()Ljava/lang/Object;", + (), + ) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&key, &key.class_definition().name(), "intValue", "()I", ()) + .await?, + -4 + ); Ok(()) } @@ -937,6 +1036,7 @@ async fn tm_02_tm_03_map_constructors_put_all_values_and_clear() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &source, + &source.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, key).await?, integer(&jvm, value).await?), @@ -946,22 +1046,40 @@ async fn tm_02_tm_03_map_constructors_put_all_values_and_clear() -> Result<()> { let map: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "(Ljava/util/Map;)V", (source.clone(),)).await?.into(); assert_eq!(ordered_integer_keys(&jvm, &map).await?, vec![1, 2, 3]); assert!( - jvm.invoke_virtual::<_, ClassInstanceRef>(&map, "comparator", "()Ljava/util/Comparator;", ()) + jvm.invoke_virtual::<_, ClassInstanceRef>(&map, &map.class_definition().name(), "comparator", "()Ljava/util/Comparator;", ()) .await? .is_null() ); assert!( - jvm.invoke_virtual::<_, bool>(&map, "containsValue", "(Ljava/lang/Object;)Z", (integer(&jvm, 20).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 20).await?,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&map, "containsValue", "(Ljava/lang/Object;)Z", (integer(&jvm, 99).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 99).await?,) + ) + .await? ); put_integer(&jvm, &map, 4, None).await?; assert!( - jvm.invoke_virtual::<_, bool>(&map, "containsValue", "(Ljava/lang/Object;)Z", (ClassInstanceRef::::from(None),)) - .await? + jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (ClassInstanceRef::::from(None),) + ) + .await? ); let reverse: ClassInstanceRef = jvm.new_class("TreeTestComparator", "(ZZZ)V", (true, false, false)).await?.into(); @@ -976,27 +1094,61 @@ async fn tm_02_tm_03_map_constructors_put_all_values_and_clear() -> Result<()> { .new_class("java/util/TreeMap", "(Ljava/util/SortedMap;)V", (sorted_source.clone(),)) .await? .into(); - let copied_comparator: ClassInstanceRef = jvm.invoke_virtual(&sorted_copy, "comparator", "()Ljava/util/Comparator;", ()).await?; + let copied_comparator: ClassInstanceRef = jvm + .invoke_virtual( + &sorted_copy, + &sorted_copy.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + (), + ) + .await?; assert_eq!(copied_comparator.identity(), reverse.identity()); assert_eq!(ordered_integer_keys(&jvm, &sorted_copy).await?, vec![3, 2, 1]); let natural_copy: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "(Ljava/util/Map;)V", (sorted_source,)).await?.into(); assert!( - jvm.invoke_virtual::<_, ClassInstanceRef>(&natural_copy, "comparator", "()Ljava/util/Comparator;", ()) - .await? - .is_null() + jvm.invoke_virtual::<_, ClassInstanceRef>( + &natural_copy, + &natural_copy.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + () + ) + .await? + .is_null() ); assert_eq!(ordered_integer_keys(&jvm, &natural_copy).await?, vec![1, 2, 3]); let destination: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "()V", ()).await?.into(); - let _: () = jvm.invoke_virtual(&destination, "putAll", "(Ljava/util/Map;)V", (source,)).await?; + let _: () = jvm + .invoke_virtual( + &destination, + &destination.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (source,), + ) + .await?; assert_eq!(ordered_integer_keys(&jvm, &destination).await?, vec![1, 2, 3]); let _: () = jvm - .invoke_virtual(&destination, "putAll", "(Ljava/util/Map;)V", (destination.clone(),)) + .invoke_virtual( + &destination, + &destination.class_definition().name(), + "putAll", + "(Ljava/util/Map;)V", + (destination.clone(),), + ) .await?; assert_eq!(ordered_integer_keys(&jvm, &destination).await?, vec![1, 2, 3]); - let _: () = jvm.invoke_virtual(&destination, "clear", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&destination, "size", "()I", ()).await?, 0); + let _: () = jvm + .invoke_virtual(&destination, &destination.class_definition().name(), "clear", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&destination, &destination.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); assert_red_black_invariants(&jvm, &destination).await?; for descriptor in ["(Ljava/util/Map;)V", "(Ljava/util/SortedMap;)V"] { @@ -1022,45 +1174,93 @@ async fn tm_04_sm_01_submaps_are_live_bounded_and_validate_nested_ranges() -> Re let sub_map: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 2).await?, integer(&jvm, 8).await?), ) .await?; assert_eq!(ordered_integer_keys(&jvm, &sub_map).await?, vec![2, 3, 4, 5, 6, 7]); - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub_map, "size", "()I", ()).await?, 6); - let first: ClassInstanceRef = jvm.invoke_virtual(&sub_map, "firstKey", "()Ljava/lang/Object;", ()).await?; - let last: ClassInstanceRef = jvm.invoke_virtual(&sub_map, "lastKey", "()Ljava/lang/Object;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "intValue", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&last, "intValue", "()I", ()).await?, 7); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&sub_map, &sub_map.class_definition().name(), "size", "()I", ()) + .await?, + 6 + ); + let first: ClassInstanceRef = jvm + .invoke_virtual(&sub_map, &sub_map.class_definition().name(), "firstKey", "()Ljava/lang/Object;", ()) + .await?; + let last: ClassInstanceRef = jvm + .invoke_virtual(&sub_map, &sub_map.class_definition().name(), "lastKey", "()Ljava/lang/Object;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "intValue", "()I", ()) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&last, &last.class_definition().name(), "intValue", "()I", ()) + .await?, + 7 + ); assert!( - jvm.invoke_virtual::<_, bool>(&sub_map, "containsValue", "(Ljava/lang/Object;)Z", (integer(&jvm, 50).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &sub_map, + &sub_map.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 50).await?,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&sub_map, "containsValue", "(Ljava/lang/Object;)Z", (integer(&jvm, 90).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &sub_map, + &sub_map.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 90).await?,) + ) + .await? ); for key in [1, 8] { let key = integer(&jvm, key).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&sub_map, "containsKey", "(Ljava/lang/Object;)Z", (key.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &sub_map, + &sub_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (key.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, ClassInstanceRef>(&sub_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) - .await? - .is_null() + jvm.invoke_virtual::<_, ClassInstanceRef>( + &sub_map, + &sub_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),) + ) + .await? + .is_null() ); assert!( - jvm.invoke_virtual::<_, ClassInstanceRef>(&sub_map, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(),)) - .await? - .is_null() + jvm.invoke_virtual::<_, ClassInstanceRef>( + &sub_map, + &sub_map.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (key.clone(),) + ) + .await? + .is_null() ); let result: Result> = jvm .invoke_virtual( &sub_map, + &sub_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key, integer(&jvm, 100).await?), @@ -1073,20 +1273,45 @@ async fn tm_04_sm_01_submaps_are_live_bounded_and_validate_nested_ranges() -> Re } let old = put_integer(&jvm, &sub_map, 3, Some(333)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&old, "intValue", "()I", ()).await?, 30); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&old, &old.class_definition().name(), "intValue", "()I", ()) + .await?, + 30 + ); let from_root: ClassInstanceRef = jvm - .invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 3).await?,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (integer(&jvm, 3).await?,), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&from_root, "intValue", "()I", ()).await?, 333); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&from_root, &from_root.class_definition().name(), "intValue", "()I", ()) + .await?, + 333 + ); put_integer(&jvm, &map, 6, Some(666)).await?; let from_view: ClassInstanceRef = jvm - .invoke_virtual(&sub_map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 6).await?,)) + .invoke_virtual( + &sub_map, + &sub_map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (integer(&jvm, 6).await?,), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&from_view, "intValue", "()I", ()).await?, 666); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&from_view, &from_view.class_definition().name(), "intValue", "()I", ()) + .await?, + 666 + ); let nested: ClassInstanceRef = jvm .invoke_virtual( &sub_map, + &sub_map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 3).await?, integer(&jvm, 7).await?), @@ -1096,6 +1321,7 @@ async fn tm_04_sm_01_submaps_are_live_bounded_and_validate_nested_ranges() -> Re let same_upper: ClassInstanceRef = jvm .invoke_virtual( &sub_map, + &sub_map.class_definition().name(), "headMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 8).await?,), @@ -1105,14 +1331,27 @@ async fn tm_04_sm_01_submaps_are_live_bounded_and_validate_nested_ranges() -> Re let empty_at_lower: ClassInstanceRef = jvm .invoke_virtual( &sub_map, + &sub_map.class_definition().name(), "headMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 2).await?,), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&empty_at_lower, "size", "()I", ()).await?, 0); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&empty_at_lower, &empty_at_lower.class_definition().name(), "size", "()I", ()) + .await?, + 0 + ); for method in ["firstKey", "lastKey"] { - let result: Result> = jvm.invoke_virtual(&empty_at_lower, method, "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual( + &empty_at_lower, + &empty_at_lower.class_definition().name(), + method, + "()Ljava/lang/Object;", + (), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("empty nested range {method} must throw"); }; @@ -1124,7 +1363,15 @@ async fn tm_04_sm_01_submaps_are_live_bounded_and_validate_nested_ranges() -> Re ("tailMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", 8), ("tailMap", "(Ljava/lang/Object;)Ljava/util/SortedMap;", 9), ] { - let result: Result> = jvm.invoke_virtual(&sub_map, method, descriptor, (integer(&jvm, endpoint).await?,)).await; + let result: Result> = jvm + .invoke_virtual( + &sub_map, + &sub_map.class_definition().name(), + method, + descriptor, + (integer(&jvm, endpoint).await?,), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("nested out-of-range endpoint must throw"); }; @@ -1133,6 +1380,7 @@ async fn tm_04_sm_01_submaps_are_live_bounded_and_validate_nested_ranges() -> Re let reversed: Result> = jvm .invoke_virtual( &sub_map, + &sub_map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 7).await?, integer(&jvm, 3).await?), @@ -1147,6 +1395,7 @@ async fn tm_04_sm_01_submaps_are_live_bounded_and_validate_nested_ranges() -> Re let out_of_range_first: Result> = jvm .invoke_virtual( &sub_map, + &sub_map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 1).await?, incompatible_upper), @@ -1163,6 +1412,7 @@ async fn tm_04_sm_01_submaps_are_live_bounded_and_validate_nested_ranges() -> Re let null_bound: Result> = jvm .invoke_virtual( &map, + &map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (ClassInstanceRef::::from(None), integer(&jvm, 3).await?), @@ -1173,7 +1423,7 @@ async fn tm_04_sm_01_submaps_are_live_bounded_and_validate_nested_ranges() -> Re }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/NullPointerException")); - let _: () = jvm.invoke_virtual(&nested, "clear", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&nested, &nested.class_definition().name(), "clear", "()V", ()).await?; assert_eq!(ordered_integer_keys(&jvm, &map).await?, vec![0, 1, 2, 7, 8, 9]); assert_red_black_invariants(&jvm, &map).await?; Ok(()) @@ -1187,79 +1437,212 @@ async fn tm_03_sm_01_views_entries_and_iterators_are_live_and_mutable() -> Resul put_integer(&jvm, &map, key, Some(key * 10)).await?; } - let keys: ClassInstanceRef = jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await?; - let values: ClassInstanceRef = jvm.invoke_virtual(&map, "values", "()Ljava/util/Collection;", ()).await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&keys, "size", "()I", ()).await?, 7); + let keys: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&keys, &keys.class_definition().name(), "size", "()I", ()) + .await?, + 7 + ); assert!( - jvm.invoke_virtual::<_, bool>(&values, "contains", "(Ljava/lang/Object;)Z", (integer(&jvm, 50).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &values, + &values.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 50).await?,) + ) + .await? ); - let entry_iterator: ClassInstanceRef = jvm.invoke_virtual(&entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let first_entry: ClassInstanceRef = jvm.invoke_virtual(&entry_iterator, "next", "()Ljava/lang/Object;", ()).await?; - let first_key: ClassInstanceRef = jvm.invoke_virtual(&first_entry, "getKey", "()Ljava/lang/Object;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&first_key, "intValue", "()I", ()).await?, 1); + let entry_iterator: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let first_entry: ClassInstanceRef = jvm + .invoke_virtual( + &entry_iterator, + &entry_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; + let first_key: ClassInstanceRef = jvm + .invoke_virtual(&first_entry, &first_entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first_key, &first_key.class_definition().name(), "intValue", "()I", ()) + .await?, + 1 + ); let replacement = integer(&jvm, 111).await?; let old: ClassInstanceRef = jvm - .invoke_virtual(&first_entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (replacement.clone(),)) + .invoke_virtual( + &first_entry, + &first_entry.class_definition().name(), + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (replacement.clone(),), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&old, "intValue", "()I", ()).await?, 10); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&old, &old.class_definition().name(), "intValue", "()I", ()) + .await?, + 10 + ); let stored: ClassInstanceRef = jvm - .invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 1).await?,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (integer(&jvm, 1).await?,), + ) .await?; assert_eq!(stored.identity(), replacement.identity()); assert!( - jvm.invoke_virtual::<_, bool>(&keys, "remove", "(Ljava/lang/Object;)Z", (integer(&jvm, 2).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &keys, + &keys.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 2).await?,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (integer(&jvm, 2).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 2).await?,) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&values, "remove", "(Ljava/lang/Object;)Z", (integer(&jvm, 30).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &values, + &values.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 30).await?,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (integer(&jvm, 3).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 3).await?,) + ) + .await? ); let candidate_map: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "()V", ()).await?.into(); put_integer(&jvm, &candidate_map, 5, Some(50)).await?; - let candidate_entries: ClassInstanceRef = jvm.invoke_virtual(&candidate_map, "entrySet", "()Ljava/util/Set;", ()).await?; - let candidate_iterator: ClassInstanceRef = jvm.invoke_virtual(&candidate_entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let candidate: ClassInstanceRef = jvm.invoke_virtual(&candidate_iterator, "next", "()Ljava/lang/Object;", ()).await?; + let candidate_entries: ClassInstanceRef = jvm + .invoke_virtual( + &candidate_map, + &candidate_map.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; + let candidate_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &candidate_entries, + &candidate_entries.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let candidate: ClassInstanceRef = jvm + .invoke_virtual( + &candidate_iterator, + &candidate_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&entries, "contains", "(Ljava/lang/Object;)Z", (candidate.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (candidate.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&entries, "remove", "(Ljava/lang/Object;)Z", (candidate,)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (candidate,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (integer(&jvm, 5).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 5).await?,) + ) + .await? ); let live_map: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "()V", ()).await?.into(); for key in [1, 3] { put_integer(&jvm, &live_map, key, Some(key)).await?; } - let live_keys: ClassInstanceRef = jvm.invoke_virtual(&live_map, "keySet", "()Ljava/util/Set;", ()).await?; - let live_iterator: ClassInstanceRef = jvm.invoke_virtual(&live_keys, "iterator", "()Ljava/util/Iterator;", ()).await?; + let live_keys: ClassInstanceRef = jvm + .invoke_virtual(&live_map, &live_map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let live_iterator: ClassInstanceRef = jvm + .invoke_virtual(&live_keys, &live_keys.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; put_integer(&jvm, &live_map, 2, Some(2)).await?; let mut seen = Vec::new(); for _ in 0..3 { - assert!(jvm.invoke_virtual::<_, bool>(&live_iterator, "hasNext", "()Z", ()).await?); - let key: ClassInstanceRef = jvm.invoke_virtual(&live_iterator, "next", "()Ljava/lang/Object;", ()).await?; - seen.push(jvm.invoke_virtual::<_, i32>(&key, "intValue", "()I", ()).await?); + assert!( + jvm.invoke_virtual::<_, bool>(&live_iterator, &live_iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + ); + let key: ClassInstanceRef = jvm + .invoke_virtual( + &live_iterator, + &live_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; + seen.push( + jvm.invoke_virtual::<_, i32>(&key, &key.class_definition().name(), "intValue", "()I", ()) + .await?, + ); } assert!( - !jvm.invoke_virtual::<_, bool>(&live_iterator, "hasNext", "()Z", ()).await?, + !jvm.invoke_virtual::<_, bool>(&live_iterator, &live_iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?, "live TreeMap iterator must terminate after each key exactly once" ); assert_eq!(seen, vec![1, 2, 3], "iterator must traverse the live tree rather than a snapshot"); @@ -1268,21 +1651,44 @@ async fn tm_03_sm_01_views_entries_and_iterators_are_live_and_mutable() -> Resul for key in [4, 2, 6, 1, 3, 5, 7] { put_integer(&jvm, &remove_map, key, Some(key)).await?; } - let remove_keys: ClassInstanceRef = jvm.invoke_virtual(&remove_map, "keySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&remove_keys, "iterator", "()Ljava/util/Iterator;", ()).await?; - let before_next: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; - let Err(JavaError::JavaException(exception)) = before_next else { + let remove_keys: ClassInstanceRef = jvm + .invoke_virtual(&remove_map, &remove_map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &remove_keys, + &remove_keys.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let before_next: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; + let Err(JavaError::JavaException(exception)) = before_next else { panic!("iterator.remove before next must throw"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/IllegalStateException")); let mut visited = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let key: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let key = jvm.invoke_virtual::<_, i32>(&key, "intValue", "()I", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let key: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let key = jvm + .invoke_virtual::<_, i32>(&key, &key.class_definition().name(), "intValue", "()I", ()) + .await?; visited.push(key); if key == 4 { - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; - let second_remove: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; + let second_remove: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = second_remove else { panic!("iterator.remove twice must throw"); }; @@ -1292,7 +1698,9 @@ async fn tm_03_sm_01_views_entries_and_iterators_are_live_and_mutable() -> Resul assert_eq!(visited, vec![1, 2, 3, 4, 5, 6, 7]); assert_eq!(ordered_integer_keys(&jvm, &remove_map).await?, vec![1, 2, 3, 5, 6, 7]); assert_red_black_invariants(&jvm, &remove_map).await?; - let exhausted: Result> = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await; + let exhausted: Result> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = exhausted else { panic!("exhausted iterator.next must throw"); }; @@ -1301,13 +1709,18 @@ async fn tm_03_sm_01_views_entries_and_iterators_are_live_and_mutable() -> Resul let range: ClassInstanceRef = jvm .invoke_virtual( &remove_map, + &remove_map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 2).await?, integer(&jvm, 7).await?), ) .await?; - let range_values: ClassInstanceRef = jvm.invoke_virtual(&range, "values", "()Ljava/util/Collection;", ()).await?; - let _: () = jvm.invoke_virtual(&range_values, "clear", "()V", ()).await?; + let range_values: ClassInstanceRef = jvm + .invoke_virtual(&range, &range.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; + let _: () = jvm + .invoke_virtual(&range_values, &range_values.class_definition().name(), "clear", "()V", ()) + .await?; assert_eq!(ordered_integer_keys(&jvm, &remove_map).await?, vec![1, 7]); assert_red_black_invariants(&jvm, &remove_map).await?; Ok(()) @@ -1327,27 +1740,58 @@ async fn sm_01_bounded_entry_views_delegate_comparator_equality_and_set_value() let range: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 6).await?, integer(&jvm, 2).await?), ) .await?; - let comparator: ClassInstanceRef = jvm.invoke_virtual(&range, "comparator", "()Ljava/util/Comparator;", ()).await?; + let comparator: ClassInstanceRef = jvm + .invoke_virtual(&range, &range.class_definition().name(), "comparator", "()Ljava/util/Comparator;", ()) + .await?; assert_eq!(comparator.identity(), reverse.identity()); assert_eq!(ordered_integer_keys(&jvm, &range).await?, vec![6, 5, 4, 3]); - let entries: ClassInstanceRef = jvm.invoke_virtual(&range, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let key: ClassInstanceRef = jvm.invoke_virtual(&entry, "getKey", "()Ljava/lang/Object;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&key, "intValue", "()I", ()).await?, 6); + let entries: ClassInstanceRef = jvm + .invoke_virtual(&range, &range.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let key: ClassInstanceRef = jvm + .invoke_virtual(&entry, &entry.class_definition().name(), "getKey", "()Ljava/lang/Object;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&key, &key.class_definition().name(), "intValue", "()I", ()) + .await?, + 6 + ); let new_value = integer(&jvm, 600).await?; let old: ClassInstanceRef = jvm - .invoke_virtual(&entry, "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (new_value.clone(),)) + .invoke_virtual( + &entry, + &entry.class_definition().name(), + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (new_value.clone(),), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&old, "intValue", "()I", ()).await?, 60); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&old, &old.class_definition().name(), "intValue", "()I", ()) + .await?, + 60 + ); let root_value: ClassInstanceRef = jvm - .invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 6).await?,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (integer(&jvm, 6).await?,), + ) .await?; assert_eq!(root_value.identity(), new_value.identity()); @@ -1355,37 +1799,94 @@ async fn sm_01_bounded_entry_views_delegate_comparator_equality_and_set_value() let _: ClassInstanceRef = jvm .invoke_virtual( &same_entry_map, + &same_entry_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 6).await?, new_value), ) .await?; - let same_entries: ClassInstanceRef = jvm.invoke_virtual(&same_entry_map, "entrySet", "()Ljava/util/Set;", ()).await?; - let same_iterator: ClassInstanceRef = jvm.invoke_virtual(&same_entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let same_entry: ClassInstanceRef = jvm.invoke_virtual(&same_iterator, "next", "()Ljava/lang/Object;", ()).await?; + let same_entries: ClassInstanceRef = jvm + .invoke_virtual( + &same_entry_map, + &same_entry_map.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; + let same_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &same_entries, + &same_entries.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let same_entry: ClassInstanceRef = jvm + .invoke_virtual( + &same_iterator, + &same_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&entry, "equals", "(Ljava/lang/Object;)Z", (same_entry.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &entry, + &entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (same_entry.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&same_entry, "equals", "(Ljava/lang/Object;)Z", (entry.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &same_entry, + &same_entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (entry.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&entry, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&same_entry, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&entry, &entry.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&same_entry, &same_entry.class_definition().name(), "hashCode", "()I", ()) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&entries, "contains", "(Ljava/lang/Object;)Z", (same_entry.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (same_entry.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&entries, "remove", "(Ljava/lang/Object;)Z", (same_entry,)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (same_entry,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (integer(&jvm, 6).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 6).await?,) + ) + .await? ); assert_eq!(ordered_integer_keys(&jvm, &range).await?, vec![5, 4, 3]); Ok(()) @@ -1400,21 +1901,36 @@ async fn tm_03_views_use_jdk_value_equals_directions() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 1).await?, stored_false), ) .await?; assert!( - jvm.invoke_virtual::<_, bool>(&map, "containsValue", "(Ljava/lang/Object;)Z", (query_true.clone(),)) - .await?, + jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsValue", + "(Ljava/lang/Object;)Z", + (query_true.clone(),) + ) + .await?, "TreeMap.containsValue uses query.equals(stored)" ); - let values: ClassInstanceRef = jvm.invoke_virtual(&map, "values", "()Ljava/util/Collection;", ()).await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; assert!( - !jvm.invoke_virtual::<_, bool>(&values, "remove", "(Ljava/lang/Object;)Z", (query_true.clone(),)) - .await?, + !jvm.invoke_virtual::<_, bool>( + &values, + &values.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (query_true.clone(),) + ) + .await?, "TreeMap.Values.remove follows JDK stored.equals(query)" ); @@ -1422,18 +1938,51 @@ async fn tm_03_views_use_jdk_value_equals_directions() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &candidate_map, + &candidate_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 1).await?, query_true), ) .await?; - let candidate_entries: ClassInstanceRef = jvm.invoke_virtual(&candidate_map, "entrySet", "()Ljava/util/Set;", ()).await?; - let candidate_iterator: ClassInstanceRef = jvm.invoke_virtual(&candidate_entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let candidate: ClassInstanceRef = jvm.invoke_virtual(&candidate_iterator, "next", "()Ljava/lang/Object;", ()).await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; + let candidate_entries: ClassInstanceRef = jvm + .invoke_virtual( + &candidate_map, + &candidate_map.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; + let candidate_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &candidate_entries, + &candidate_entries.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let candidate: ClassInstanceRef = jvm + .invoke_virtual( + &candidate_iterator, + &candidate_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; assert!( - !jvm.invoke_virtual::<_, bool>(&entries, "contains", "(Ljava/lang/Object;)Z", (candidate,)) - .await?, + !jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (candidate,) + ) + .await?, "TreeMap.EntrySet.contains follows JDK storedValue.equals(candidateValue)" ); @@ -1442,18 +1991,31 @@ async fn tm_03_views_use_jdk_value_equals_directions() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 2).await?, stored_true), ) .await?; assert!( - jvm.invoke_virtual::<_, bool>(&values, "remove", "(Ljava/lang/Object;)Z", (query_false,)) - .await? + jvm.invoke_virtual::<_, bool>( + &values, + &values.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (query_false,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (integer(&jvm, 2).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 2).await?,) + ) + .await? ); let stored_true: ClassInstanceRef = jvm.new_class("TreeEqualsValue", "(IZ)V", (3, true)).await?.into(); @@ -1461,6 +2023,7 @@ async fn tm_03_views_use_jdk_value_equals_directions() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 3).await?, stored_true), @@ -1470,25 +2033,68 @@ async fn tm_03_views_use_jdk_value_equals_directions() -> Result<()> { let _: ClassInstanceRef = jvm .invoke_virtual( &candidate_map, + &candidate_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 3).await?, candidate_false), ) .await?; - let candidate_entries: ClassInstanceRef = jvm.invoke_virtual(&candidate_map, "entrySet", "()Ljava/util/Set;", ()).await?; - let candidate_iterator: ClassInstanceRef = jvm.invoke_virtual(&candidate_entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let candidate: ClassInstanceRef = jvm.invoke_virtual(&candidate_iterator, "next", "()Ljava/lang/Object;", ()).await?; + let candidate_entries: ClassInstanceRef = jvm + .invoke_virtual( + &candidate_map, + &candidate_map.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; + let candidate_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &candidate_entries, + &candidate_entries.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let candidate: ClassInstanceRef = jvm + .invoke_virtual( + &candidate_iterator, + &candidate_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&entries, "contains", "(Ljava/lang/Object;)Z", (candidate.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (candidate.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&entries, "remove", "(Ljava/lang/Object;)Z", (candidate,)) - .await? + jvm.invoke_virtual::<_, bool>( + &entries, + &entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (candidate,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&map, "containsKey", "(Ljava/lang/Object;)Z", (integer(&jvm, 3).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &map, + &map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 3).await?,) + ) + .await? ); let changing_map: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "()V", ()).await?.into(); @@ -1502,19 +2108,45 @@ async fn tm_03_views_use_jdk_value_equals_directions() -> Result<()> { ) .await? .into(); - let changing_entries: ClassInstanceRef = jvm.invoke_virtual(&changing_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let changing_entries: ClassInstanceRef = jvm + .invoke_virtual( + &changing_map, + &changing_map.class_definition().name(), + "entrySet", + "()Ljava/util/Set;", + (), + ) + .await?; assert!( - jvm.invoke_virtual::<_, bool>(&changing_entries, "remove", "(Ljava/lang/Object;)Z", (changing_entry.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &changing_entries, + &changing_entries.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (changing_entry.clone(),) + ) + .await? ); assert_eq!(jvm.get_field::(&changing_entry, "keyCalls", "I").await?, 1); assert!( - !jvm.invoke_virtual::<_, bool>(&changing_map, "containsKey", "(Ljava/lang/Object;)Z", (integer(&jvm, 10).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &changing_map, + &changing_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 10).await?,) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&changing_map, "containsKey", "(Ljava/lang/Object;)Z", (integer(&jvm, 20).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &changing_map, + &changing_map.class_definition().name(), + "containsKey", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 20).await?,) + ) + .await? ); Ok(()) } @@ -1529,18 +2161,31 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let sub_map: ClassInstanceRef = jvm .invoke_virtual( &map, + &map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 2).await?, integer(&jvm, 4).await?), ) .await?; - let keys: ClassInstanceRef = jvm.invoke_virtual(&map, "keySet", "()Ljava/util/Set;", ()).await?; - let values: ClassInstanceRef = jvm.invoke_virtual(&map, "values", "()Ljava/util/Collection;", ()).await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - let sub_keys: ClassInstanceRef = jvm.invoke_virtual(&sub_map, "keySet", "()Ljava/util/Set;", ()).await?; - let sub_values: ClassInstanceRef = jvm.invoke_virtual(&sub_map, "values", "()Ljava/util/Collection;", ()).await?; - let sub_entries: ClassInstanceRef = jvm.invoke_virtual(&sub_map, "entrySet", "()Ljava/util/Set;", ()).await?; + let keys: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let values: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let sub_keys: ClassInstanceRef = jvm + .invoke_virtual(&sub_map, &sub_map.class_definition().name(), "keySet", "()Ljava/util/Set;", ()) + .await?; + let sub_values: ClassInstanceRef = jvm + .invoke_virtual(&sub_map, &sub_map.class_definition().name(), "values", "()Ljava/util/Collection;", ()) + .await?; + let sub_entries: ClassInstanceRef = jvm + .invoke_virtual(&sub_map, &sub_map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; let sentinel = integer(&jvm, -1).await?; let mut key_destination: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/Integer;", 6).await?.into(); @@ -1558,12 +2203,28 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( ) .await?; let key_result: ClassInstanceRef> = jvm - .invoke_virtual(&keys, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (key_destination.clone(),)) + .invoke_virtual( + &keys, + &keys.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (key_destination.clone(),), + ) .await?; assert_eq!(key_result.identity(), key_destination.identity()); let key_elements = jvm.load_array::>(&key_result, 0, 6).await?; for (index, expected) in [1, 2, 3, 4].into_iter().enumerate() { - assert_eq!(jvm.invoke_virtual::<_, i32>(&key_elements[index], "intValue", "()I", ()).await?, expected); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &key_elements[index], + &key_elements[index].class_definition().name(), + "intValue", + "()I", + () + ) + .await?, + expected + ); } assert!(key_elements[4].is_null(), "a reused oversized destination needs a null terminator"); assert_eq!( @@ -1576,6 +2237,7 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let value_result: ClassInstanceRef> = jvm .invoke_virtual( &values, + &values.class_definition().name(), "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (value_destination.clone(),), @@ -1587,14 +2249,27 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let value_elements = jvm.load_array::>(&value_result, 0, 4).await?; for (index, expected) in [10, 20, 30, 40].into_iter().enumerate() { assert_eq!( - jvm.invoke_virtual::<_, i32>(&value_elements[index], "intValue", "()I", ()).await?, + jvm.invoke_virtual::<_, i32>( + &value_elements[index], + &value_elements[index].class_definition().name(), + "intValue", + "()I", + () + ) + .await?, expected ); } let entry_destination: ClassInstanceRef> = jvm.instantiate_array("Ljava/util/Map$Entry;", 0).await?.into(); let entry_result: ClassInstanceRef> = jvm - .invoke_virtual(&entries, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (entry_destination,)) + .invoke_virtual( + &entries, + &entries.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (entry_destination,), + ) .await?; assert_eq!(entry_result.class_definition().name(), "[Ljava/util/Map$Entry;"); let root_entries = jvm.load_array::>(&entry_result, 0, 4).await?; @@ -1602,13 +2277,20 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let _: ClassInstanceRef = jvm .invoke_virtual( &root_entries[0], + &root_entries[0].class_definition().name(), "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (replacement.clone(),), ) .await?; let stored: ClassInstanceRef = jvm - .invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 1).await?,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (integer(&jvm, 1).await?,), + ) .await?; assert_eq!( stored.identity(), @@ -1626,6 +2308,7 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let sub_key_result: ClassInstanceRef> = jvm .invoke_virtual( &sub_keys, + &sub_keys.class_definition().name(), "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (sub_key_destination.clone(),), @@ -1633,8 +2316,28 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( .await?; assert_eq!(sub_key_result.identity(), sub_key_destination.identity()); let sub_key_elements = jvm.load_array::>(&sub_key_result, 0, 4).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub_key_elements[0], "intValue", "()I", ()).await?, 2); - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub_key_elements[1], "intValue", "()I", ()).await?, 3); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &sub_key_elements[0], + &sub_key_elements[0].class_definition().name(), + "intValue", + "()I", + () + ) + .await?, + 2 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &sub_key_elements[1], + &sub_key_elements[1].class_definition().name(), + "intValue", + "()I", + () + ) + .await?, + 3 + ); assert!(sub_key_elements[2].is_null()); assert_eq!(sub_key_elements[3].identity(), sentinel.identity()); @@ -1642,6 +2345,7 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let sub_value_result: ClassInstanceRef> = jvm .invoke_virtual( &sub_values, + &sub_values.class_definition().name(), "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (sub_value_destination,), @@ -1649,13 +2353,34 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( .await?; assert_eq!(sub_value_result.class_definition().name(), "[Ljava/lang/Integer;"); let sub_value_elements = jvm.load_array::>(&sub_value_result, 0, 2).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub_value_elements[0], "intValue", "()I", ()).await?, 20); - assert_eq!(jvm.invoke_virtual::<_, i32>(&sub_value_elements[1], "intValue", "()I", ()).await?, 30); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &sub_value_elements[0], + &sub_value_elements[0].class_definition().name(), + "intValue", + "()I", + () + ) + .await?, + 20 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &sub_value_elements[1], + &sub_value_elements[1].class_definition().name(), + "intValue", + "()I", + () + ) + .await?, + 30 + ); let sub_entry_destination: ClassInstanceRef> = jvm.instantiate_array("Ljava/util/Map$Entry;", 0).await?.into(); let sub_entry_result: ClassInstanceRef> = jvm .invoke_virtual( &sub_entries, + &sub_entries.class_definition().name(), "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (sub_entry_destination,), @@ -1666,13 +2391,20 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let _: ClassInstanceRef = jvm .invoke_virtual( &sub_entry_elements[0], + &sub_entry_elements[0].class_definition().name(), "setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", (replacement.clone(),), ) .await?; let stored: ClassInstanceRef = jvm - .invoke_virtual(&map, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 2).await?,)) + .invoke_virtual( + &map, + &map.class_definition().name(), + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + (integer(&jvm, 2).await?,), + ) .await?; assert_eq!( stored.identity(), @@ -1688,7 +2420,13 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( ] { let incompatible: ClassInstanceRef> = jvm.instantiate_array("LTreeEqualsValue;", 4).await?.into(); let result: Result>> = jvm - .invoke_virtual(&view, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (incompatible,)) + .invoke_virtual( + &view, + &view.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (incompatible,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{name}.toArray must reject an incompatible component type"); @@ -1698,7 +2436,13 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( for (name, view) in [("TreeMap.entrySet", entries), ("SubMap.entrySet", sub_entries)] { let incompatible: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/Integer;", 4).await?.into(); let result: Result>> = jvm - .invoke_virtual(&view, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (incompatible,)) + .invoke_virtual( + &view, + &view.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (incompatible,), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{name}.toArray must reject an incompatible component type"); @@ -1711,6 +2455,7 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let _: ClassInstanceRef = jvm .invoke_virtual( &partial_map, + &partial_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 1).await?, first_value.clone()), @@ -1721,6 +2466,7 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let _: ClassInstanceRef = jvm .invoke_virtual( &partial_map, + &partial_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (integer(&jvm, 3).await?, third_value), @@ -1729,13 +2475,30 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( let partial_sub_map: ClassInstanceRef = jvm .invoke_virtual( &partial_map, + &partial_map.class_definition().name(), "subMap", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;", (integer(&jvm, 1).await?, integer(&jvm, 3).await?), ) .await?; - let partial_values: ClassInstanceRef = jvm.invoke_virtual(&partial_map, "values", "()Ljava/util/Collection;", ()).await?; - let partial_sub_values: ClassInstanceRef = jvm.invoke_virtual(&partial_sub_map, "values", "()Ljava/util/Collection;", ()).await?; + let partial_values: ClassInstanceRef = jvm + .invoke_virtual( + &partial_map, + &partial_map.class_definition().name(), + "values", + "()Ljava/util/Collection;", + (), + ) + .await?; + let partial_sub_values: ClassInstanceRef = jvm + .invoke_virtual( + &partial_sub_map, + &partial_sub_map.class_definition().name(), + "values", + "()Ljava/util/Collection;", + (), + ) + .await?; for (name, view) in [("TreeMap.values", partial_values), ("SubMap.values", partial_sub_values)] { let array_sentinel: ClassInstanceRef = jvm.new_class("TreeEqualsValue", "(IZ)V", (99, true)).await?.into(); let mut destination: ClassInstanceRef> = jvm.instantiate_array("LTreeEqualsValue;", 4).await?.into(); @@ -1751,7 +2514,13 @@ async fn tm_03_sm_01_typed_to_array_preserves_component_and_live_view_contracts( ) .await?; let result: Result>> = jvm - .invoke_virtual(&view, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", (destination.clone(),)) + .invoke_virtual( + &view, + &view.class_definition().name(), + "toArray", + "([Ljava/lang/Object;)[Ljava/lang/Object;", + (destination.clone(),), + ) .await; let Err(JavaError::JavaException(exception)) = result else { panic!("{name}.toArray must fail at the first incompatible element"); @@ -1775,9 +2544,15 @@ async fn tm_03_entry_equals_short_circuits_before_reading_value() -> Result<()> let jvm = tree_test_jvm().await?; let map: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "()V", ()).await?.into(); put_integer(&jvm, &map, 1, Some(10)).await?; - let entries: ClassInstanceRef = jvm.invoke_virtual(&map, "entrySet", "()Ljava/util/Set;", ()).await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&entries, "iterator", "()Ljava/util/Iterator;", ()).await?; - let entry: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let entries: ClassInstanceRef = jvm + .invoke_virtual(&map, &map.class_definition().name(), "entrySet", "()Ljava/util/Set;", ()) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&entries, &entries.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + let entry: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; let different_key: ClassInstanceRef = jvm .new_class( @@ -1788,8 +2563,14 @@ async fn tm_03_entry_equals_short_circuits_before_reading_value() -> Result<()> .await? .into(); assert!( - !jvm.invoke_virtual::<_, bool>(&entry, "equals", "(Ljava/lang/Object;)Z", (different_key.clone(),)) - .await? + !jvm.invoke_virtual::<_, bool>( + &entry, + &entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (different_key.clone(),) + ) + .await? ); assert_eq!( jvm.get_field::(&different_key, "valueCalls", "I").await?, @@ -1805,7 +2586,15 @@ async fn tm_03_entry_equals_short_circuits_before_reading_value() -> Result<()> ) .await? .into(); - let result: Result = jvm.invoke_virtual(&entry, "equals", "(Ljava/lang/Object;)Z", (equal_key.clone(),)).await; + let result: Result = jvm + .invoke_virtual( + &entry, + &entry.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (equal_key.clone(),), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("TreeMap.Entry.equals must call getValue after an equal key and propagate its exception"); }; @@ -1824,16 +2613,30 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra put_integer(&jvm, &map, 2, Some(20)).await?; } assert!( - jvm.invoke_virtual::<_, bool>(&tree_map, "equals", "(Ljava/lang/Object;)Z", (hash_map.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &tree_map, + &tree_map.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (hash_map.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&hash_map, "equals", "(Ljava/lang/Object;)Z", (tree_map.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &hash_map, + &hash_map.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (tree_map.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&tree_map, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&hash_map, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&tree_map, &tree_map.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&hash_map, &hash_map.class_definition().name(), "hashCode", "()I", ()) + .await? ); let incompatible_hash_map: ClassInstanceRef = jvm.new_class("java/util/HashMap", "()V", ()).await?.into(); @@ -1841,20 +2644,28 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra let _: ClassInstanceRef = jvm .invoke_virtual( &incompatible_hash_map, + &incompatible_hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (plain_key, ClassInstanceRef::::from(None)), ) .await?; assert!( - !jvm.invoke_virtual::<_, bool>(&incompatible_hash_map, "equals", "(Ljava/lang/Object;)Z", (tree_map.clone(),)) - .await?, - "AbstractMap.equals must convert TreeMap CCE to false" - ); - let null_key_hash_map: ClassInstanceRef = jvm.new_class("java/util/HashMap", "()V", ()).await?.into(); - let _: ClassInstanceRef = jvm - .invoke_virtual( + !jvm.invoke_virtual::<_, bool>( + &incompatible_hash_map, + &incompatible_hash_map.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (tree_map.clone(),) + ) + .await?, + "AbstractMap.equals must convert TreeMap CCE to false" + ); + let null_key_hash_map: ClassInstanceRef = jvm.new_class("java/util/HashMap", "()V", ()).await?.into(); + let _: ClassInstanceRef = jvm + .invoke_virtual( &null_key_hash_map, + &null_key_hash_map.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (ClassInstanceRef::::from(None), ClassInstanceRef::::from(None)), @@ -1863,8 +2674,14 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra let single_tree_map: ClassInstanceRef = jvm.new_class("java/util/TreeMap", "()V", ()).await?.into(); put_integer(&jvm, &single_tree_map, 1, None).await?; assert!( - !jvm.invoke_virtual::<_, bool>(&null_key_hash_map, "equals", "(Ljava/lang/Object;)Z", (single_tree_map.clone(),)) - .await?, + !jvm.invoke_virtual::<_, bool>( + &null_key_hash_map, + &null_key_hash_map.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (single_tree_map.clone(),) + ) + .await?, "AbstractMap.equals must convert TreeMap NPE to false" ); @@ -1877,16 +2694,36 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra let same_key_hash_map: ClassInstanceRef = jvm.new_class("java/util/HashMap", "()V", ()).await?.into(); put_integer(&jvm, &same_key_hash_map, -5, None).await?; assert!( - jvm.invoke_virtual::<_, bool>(&equivalent_tree_map, "equals", "(Ljava/lang/Object;)Z", (same_key_hash_map.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &equivalent_tree_map, + &equivalent_tree_map.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (same_key_hash_map.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&same_key_hash_map, "equals", "(Ljava/lang/Object;)Z", (equivalent_tree_map.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &same_key_hash_map, + &same_key_hash_map.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (equivalent_tree_map.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&equivalent_tree_map, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&same_key_hash_map, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>( + &equivalent_tree_map, + &equivalent_tree_map.class_definition().name(), + "hashCode", + "()I", + () + ) + .await?, + jvm.invoke_virtual::<_, i32>(&same_key_hash_map, &same_key_hash_map.class_definition().name(), "hashCode", "()I", ()) + .await? ); let comparator_equivalent_hash_map: ClassInstanceRef = jvm.new_class("java/util/HashMap", "()V", ()).await?.into(); @@ -1894,6 +2731,7 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra assert!( !jvm.invoke_virtual::<_, bool>( &equivalent_tree_map, + &equivalent_tree_map.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (comparator_equivalent_hash_map.clone(),) @@ -1904,6 +2742,7 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra assert!( jvm.invoke_virtual::<_, bool>( &comparator_equivalent_hash_map, + &comparator_equivalent_hash_map.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (equivalent_tree_map.clone(),) @@ -1912,9 +2751,22 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra "HashMap equality queries TreeMap with the comparator-equivalent key" ); assert_ne!( - jvm.invoke_virtual::<_, i32>(&equivalent_tree_map, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&comparator_equivalent_hash_map, "hashCode", "()I", ()) - .await?, + jvm.invoke_virtual::<_, i32>( + &equivalent_tree_map, + &equivalent_tree_map.class_definition().name(), + "hashCode", + "()I", + () + ) + .await?, + jvm.invoke_virtual::<_, i32>( + &comparator_equivalent_hash_map, + &comparator_equivalent_hash_map.class_definition().name(), + "hashCode", + "()I", + () + ) + .await?, "a comparator inconsistent with equals intentionally violates the general Map contract" ); @@ -1923,22 +2775,42 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra for set in [tree_set.clone(), hash_set.clone()] { for key in [1, 2, 3] { assert!( - jvm.invoke_virtual::<_, bool>(&set, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, key).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &set, + &set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, key).await?,) + ) + .await? ); } } assert!( - jvm.invoke_virtual::<_, bool>(&tree_set, "equals", "(Ljava/lang/Object;)Z", (hash_set.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &tree_set, + &tree_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (hash_set.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&hash_set, "equals", "(Ljava/lang/Object;)Z", (tree_set.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &hash_set, + &hash_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (tree_set.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&tree_set, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&hash_set, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&tree_set, &tree_set.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&hash_set, &hash_set.class_definition().name(), "hashCode", "()I", ()) + .await? ); let nulls_first: ClassInstanceRef = jvm.new_class("TreeTestComparator", "(ZZZ)V", (false, true, false)).await?.into(); @@ -1949,54 +2821,113 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra let null_hash_set: ClassInstanceRef = jvm.new_class("java/util/HashSet", "()V", ()).await?.into(); for set in [null_tree_set.clone(), null_hash_set.clone()] { assert!( - jvm.invoke_virtual::<_, bool>(&set, "add", "(Ljava/lang/Object;)Z", (ClassInstanceRef::::from(None),)) - .await? + jvm.invoke_virtual::<_, bool>( + &set, + &set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (ClassInstanceRef::::from(None),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&set, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, 1).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &set, + &set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 1).await?,) + ) + .await? ); } assert!( - jvm.invoke_virtual::<_, bool>(&null_tree_set, "equals", "(Ljava/lang/Object;)Z", (null_hash_set.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &null_tree_set, + &null_tree_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_hash_set.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&null_hash_set, "equals", "(Ljava/lang/Object;)Z", (null_tree_set.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &null_hash_set, + &null_hash_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (null_tree_set.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&null_tree_set, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&null_hash_set, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>(&null_tree_set, &null_tree_set.class_definition().name(), "hashCode", "()I", ()) + .await?, + jvm.invoke_virtual::<_, i32>(&null_hash_set, &null_hash_set.class_definition().name(), "hashCode", "()I", ()) + .await? ); let equivalent_tree_set: ClassInstanceRef = jvm.new_class("java/util/TreeSet", "(Ljava/util/Comparator;)V", (absolute,)).await?.into(); assert!( - jvm.invoke_virtual::<_, bool>(&equivalent_tree_set, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, -5).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &equivalent_tree_set, + &equivalent_tree_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, -5).await?,) + ) + .await? ); let same_key_hash_set: ClassInstanceRef = jvm.new_class("java/util/HashSet", "()V", ()).await?.into(); assert!( - jvm.invoke_virtual::<_, bool>(&same_key_hash_set, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, -5).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &same_key_hash_set, + &same_key_hash_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, -5).await?,) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&equivalent_tree_set, "equals", "(Ljava/lang/Object;)Z", (same_key_hash_set.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &equivalent_tree_set, + &equivalent_tree_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (same_key_hash_set.clone(),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&same_key_hash_set, "equals", "(Ljava/lang/Object;)Z", (equivalent_tree_set.clone(),)) - .await? + jvm.invoke_virtual::<_, bool>( + &same_key_hash_set, + &same_key_hash_set.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (equivalent_tree_set.clone(),) + ) + .await? ); assert_eq!( - jvm.invoke_virtual::<_, i32>(&equivalent_tree_set, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&same_key_hash_set, "hashCode", "()I", ()).await? + jvm.invoke_virtual::<_, i32>( + &equivalent_tree_set, + &equivalent_tree_set.class_definition().name(), + "hashCode", + "()I", + () + ) + .await?, + jvm.invoke_virtual::<_, i32>(&same_key_hash_set, &same_key_hash_set.class_definition().name(), "hashCode", "()I", ()) + .await? ); let comparator_equivalent_hash_set: ClassInstanceRef = jvm.new_class("java/util/HashSet", "()V", ()).await?.into(); assert!( jvm.invoke_virtual::<_, bool>( &comparator_equivalent_hash_set, + &comparator_equivalent_hash_set.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (integer(&jvm, 5).await?,) @@ -2006,6 +2937,7 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra assert!( jvm.invoke_virtual::<_, bool>( &equivalent_tree_set, + &equivalent_tree_set.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (comparator_equivalent_hash_set.clone(),) @@ -2016,6 +2948,7 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra assert!( !jvm.invoke_virtual::<_, bool>( &comparator_equivalent_hash_set, + &comparator_equivalent_hash_set.class_definition().name(), "equals", "(Ljava/lang/Object;)Z", (equivalent_tree_set.clone(),) @@ -2024,9 +2957,22 @@ async fn tm_03_ts_02_cross_implementation_equals_and_hash_code_follow_jdk_contra "HashSet.containsAll uses Object.equals" ); assert_ne!( - jvm.invoke_virtual::<_, i32>(&equivalent_tree_set, "hashCode", "()I", ()).await?, - jvm.invoke_virtual::<_, i32>(&comparator_equivalent_hash_set, "hashCode", "()I", ()) - .await?, + jvm.invoke_virtual::<_, i32>( + &equivalent_tree_set, + &equivalent_tree_set.class_definition().name(), + "hashCode", + "()I", + () + ) + .await?, + jvm.invoke_virtual::<_, i32>( + &comparator_equivalent_hash_set, + &comparator_equivalent_hash_set.class_definition().name(), + "hashCode", + "()I", + () + ) + .await?, "a comparator inconsistent with equals intentionally violates the general Set contract" ); Ok(()) @@ -2038,33 +2984,79 @@ async fn ts_02_ts_03_tree_set_core_constructors_and_comparator_equivalence() -> let set: ClassInstanceRef = jvm.new_class("java/util/TreeSet", "()V", ()).await?.into(); for (key, expected_added) in [(3, true), (1, true), (2, true), (2, false)] { assert_eq!( - jvm.invoke_virtual::<_, bool>(&set, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, key).await?,)) - .await?, + jvm.invoke_virtual::<_, bool>( + &set, + &set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, key).await?,) + ) + .await?, expected_added ); } - assert_eq!(jvm.invoke_virtual::<_, i32>(&set, "size", "()I", ()).await?, 3); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&set, &set.class_definition().name(), "size", "()I", ()) + .await?, + 3 + ); assert!( - jvm.invoke_virtual::<_, bool>(&set, "contains", "(Ljava/lang/Object;)Z", (integer(&jvm, 2).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &set, + &set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 2).await?,) + ) + .await? + ); + let first: ClassInstanceRef = jvm + .invoke_virtual(&set, &set.class_definition().name(), "first", "()Ljava/lang/Object;", ()) + .await?; + let last: ClassInstanceRef = jvm + .invoke_virtual(&set, &set.class_definition().name(), "last", "()Ljava/lang/Object;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&first, &first.class_definition().name(), "intValue", "()I", ()) + .await?, + 1 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&last, &last.class_definition().name(), "intValue", "()I", ()) + .await?, + 3 ); - let first: ClassInstanceRef = jvm.invoke_virtual(&set, "first", "()Ljava/lang/Object;", ()).await?; - let last: ClassInstanceRef = jvm.invoke_virtual(&set, "last", "()Ljava/lang/Object;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&first, "intValue", "()I", ()).await?, 1); - assert_eq!(jvm.invoke_virtual::<_, i32>(&last, "intValue", "()I", ()).await?, 3); assert!( - jvm.invoke_virtual::<_, bool>(&set, "remove", "(Ljava/lang/Object;)Z", (integer(&jvm, 2).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &set, + &set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 2).await?,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&set, "remove", "(Ljava/lang/Object;)Z", (integer(&jvm, 2).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &set, + &set.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 2).await?,) + ) + .await? ); let collection: ClassInstanceRef = jvm.new_class("java/util/ArrayList", "()V", ()).await?.into(); for key in [4, 2, 3, 2] { let _: bool = jvm - .invoke_virtual(&collection, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, key).await?,)) + .invoke_virtual( + &collection, + &collection.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, key).await?,), + ) .await?; } let collection_set: ClassInstanceRef = jvm @@ -2072,16 +3064,38 @@ async fn ts_02_ts_03_tree_set_core_constructors_and_comparator_equivalence() -> .await? .into(); let mut collection_values = Vec::new(); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&collection_set, "iterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - collection_values.push(jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?); + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &collection_set, + &collection_set.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + collection_values.push( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?, + ); } assert_eq!(collection_values, vec![2, 3, 4]); assert!( - jvm.invoke_virtual::<_, ClassInstanceRef>(&collection_set, "comparator", "()Ljava/util/Comparator;", ()) - .await? - .is_null() + jvm.invoke_virtual::<_, ClassInstanceRef>( + &collection_set, + &collection_set.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + () + ) + .await? + .is_null() ); let reverse: ClassInstanceRef = jvm.new_class("TreeTestComparator", "(ZZZ)V", (true, false, false)).await?.into(); @@ -2091,20 +3105,50 @@ async fn ts_02_ts_03_tree_set_core_constructors_and_comparator_equivalence() -> .into(); for key in [1, 3, 2] { let _: bool = jvm - .invoke_virtual(&reverse_set, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, key).await?,)) + .invoke_virtual( + &reverse_set, + &reverse_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, key).await?,), + ) .await?; } let sorted_copy: ClassInstanceRef = jvm .new_class("java/util/TreeSet", "(Ljava/util/SortedSet;)V", (reverse_set.clone(),)) .await? .into(); - let copied_comparator: ClassInstanceRef = jvm.invoke_virtual(&sorted_copy, "comparator", "()Ljava/util/Comparator;", ()).await?; + let copied_comparator: ClassInstanceRef = jvm + .invoke_virtual( + &sorted_copy, + &sorted_copy.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + (), + ) + .await?; assert_eq!(copied_comparator.identity(), reverse.identity()); let mut copied_values = Vec::new(); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&sorted_copy, "iterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - copied_values.push(jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?); + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &sorted_copy, + &sorted_copy.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + copied_values.push( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?, + ); } assert_eq!(copied_values, vec![3, 2, 1]); @@ -2113,30 +3157,70 @@ async fn ts_02_ts_03_tree_set_core_constructors_and_comparator_equivalence() -> .await? .into(); assert!( - jvm.invoke_virtual::<_, ClassInstanceRef>(&collection_copy, "comparator", "()Ljava/util/Comparator;", ()) - .await? - .is_null() + jvm.invoke_virtual::<_, ClassInstanceRef>( + &collection_copy, + &collection_copy.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + () + ) + .await? + .is_null() ); let mut natural_values = Vec::new(); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&collection_copy, "iterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - natural_values.push(jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?); + let iterator: ClassInstanceRef = jvm + .invoke_virtual( + &collection_copy, + &collection_copy.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + natural_values.push( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?, + ); } assert_eq!(natural_values, vec![1, 2, 3]); let absolute: ClassInstanceRef = jvm.new_class("TreeTestComparator", "(ZZZ)V", (false, false, true)).await?.into(); let equivalent: ClassInstanceRef = jvm.new_class("java/util/TreeSet", "(Ljava/util/Comparator;)V", (absolute,)).await?.into(); assert!( - jvm.invoke_virtual::<_, bool>(&equivalent, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, -5).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &equivalent, + &equivalent.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, -5).await?,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&equivalent, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, 5).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &equivalent, + &equivalent.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 5).await?,) + ) + .await? + ); + let retained: ClassInstanceRef = jvm + .invoke_virtual(&equivalent, &equivalent.class_definition().name(), "first", "()Ljava/lang/Object;", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&retained, &retained.class_definition().name(), "intValue", "()I", ()) + .await?, + -5 ); - let retained: ClassInstanceRef = jvm.invoke_virtual(&equivalent, "first", "()Ljava/lang/Object;", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&retained, "intValue", "()I", ()).await?, -5); for descriptor in ["(Ljava/util/Collection;)V", "(Ljava/util/SortedSet;)V"] { let result: Result> = jvm @@ -2149,9 +3233,11 @@ async fn ts_02_ts_03_tree_set_core_constructors_and_comparator_equivalence() -> assert!(jvm.is_instance(exception.as_ref(), "java/lang/NullPointerException")); } - let _: () = jvm.invoke_virtual(&set, "clear", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&set, &set.class_definition().name(), "clear", "()V", ()).await?; for method in ["first", "last"] { - let result: Result> = jvm.invoke_virtual(&set, method, "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&set, &set.class_definition().name(), method, "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("empty TreeSet.{method} must throw"); }; @@ -2166,68 +3252,142 @@ async fn ts_03_tree_set_ranges_are_live_bounded_and_iterator_mutable() -> Result let set: ClassInstanceRef = jvm.new_class("java/util/TreeSet", "()V", ()).await?.into(); for key in 0..10 { let _: bool = jvm - .invoke_virtual(&set, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, key).await?,)) + .invoke_virtual( + &set, + &set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, key).await?,), + ) .await?; } let range: ClassInstanceRef = jvm .invoke_virtual( &set, + &set.class_definition().name(), "subSet", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedSet;", (integer(&jvm, 2).await?, integer(&jvm, 8).await?), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&range, "size", "()I", ()).await?, 6); + assert_eq!( + jvm.invoke_virtual::<_, i32>(&range, &range.class_definition().name(), "size", "()I", ()) + .await?, + 6 + ); assert!( - jvm.invoke_virtual::<_, bool>(&range, "contains", "(Ljava/lang/Object;)Z", (integer(&jvm, 2).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &range, + &range.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 2).await?,) + ) + .await? ); assert!( - !jvm.invoke_virtual::<_, bool>(&range, "contains", "(Ljava/lang/Object;)Z", (integer(&jvm, 8).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &range, + &range.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 8).await?,) + ) + .await? ); let nested: ClassInstanceRef = jvm - .invoke_virtual(&range, "tailSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (integer(&jvm, 4).await?,)) + .invoke_virtual( + &range, + &range.class_definition().name(), + "tailSet", + "(Ljava/lang/Object;)Ljava/util/SortedSet;", + (integer(&jvm, 4).await?,), + ) + .await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&nested, &nested.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) .await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&nested, "iterator", "()Ljava/util/Iterator;", ()).await?; let mut nested_values = Vec::new(); - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - let value = jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + let value = jvm + .invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?; nested_values.push(value); if value == 5 { - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; } } assert_eq!(nested_values, vec![4, 5, 6, 7]); assert!( - !jvm.invoke_virtual::<_, bool>(&set, "contains", "(Ljava/lang/Object;)Z", (integer(&jvm, 5).await?,)) - .await? + !jvm.invoke_virtual::<_, bool>( + &set, + &set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 5).await?,) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&range, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, 5).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &range, + &range.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 5).await?,) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&set, "contains", "(Ljava/lang/Object;)Z", (integer(&jvm, 5).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &set, + &set.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 5).await?,) + ) + .await? ); let outside_add: Result = jvm - .invoke_virtual(&range, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, 8).await?,)) + .invoke_virtual( + &range, + &range.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 8).await?,), + ) .await; let Err(JavaError::JavaException(exception)) = outside_add else { panic!("range add at exclusive upper bound must throw"); }; assert!(jvm.is_instance(exception.as_ref(), "java/lang/IllegalArgumentException")); - let _: () = jvm.invoke_virtual(&nested, "clear", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&nested, &nested.class_definition().name(), "clear", "()V", ()).await?; let mut remaining = Vec::new(); - let iterator: ClassInstanceRef = jvm.invoke_virtual(&set, "iterator", "()Ljava/util/Iterator;", ()).await?; - while jvm.invoke_virtual::<_, bool>(&iterator, "hasNext", "()Z", ()).await? { - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; - remaining.push(jvm.invoke_virtual::<_, i32>(&value, "intValue", "()I", ()).await?); + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&set, &set.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; + while jvm + .invoke_virtual::<_, bool>(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await? + { + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; + remaining.push( + jvm.invoke_virtual::<_, i32>(&value, &value.class_definition().name(), "intValue", "()I", ()) + .await?, + ); } assert_eq!(remaining, vec![0, 1, 2, 3, 8, 9]); @@ -2237,27 +3397,56 @@ async fn ts_03_tree_set_ranges_are_live_bounded_and_iterator_mutable() -> Result .await? .into(); assert!( - jvm.invoke_virtual::<_, bool>(&null_set, "add", "(Ljava/lang/Object;)Z", (ClassInstanceRef::::from(None),)) - .await? + jvm.invoke_virtual::<_, bool>( + &null_set, + &null_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (ClassInstanceRef::::from(None),) + ) + .await? ); assert!( - jvm.invoke_virtual::<_, bool>(&null_set, "add", "(Ljava/lang/Object;)Z", (integer(&jvm, 1).await?,)) - .await? + jvm.invoke_virtual::<_, bool>( + &null_set, + &null_set.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (integer(&jvm, 1).await?,) + ) + .await? ); - let first: ClassInstanceRef = jvm.invoke_virtual(&null_set, "first", "()Ljava/lang/Object;", ()).await?; + let first: ClassInstanceRef = jvm + .invoke_virtual(&null_set, &null_set.class_definition().name(), "first", "()Ljava/lang/Object;", ()) + .await?; assert!(first.is_null()); - let comparator: ClassInstanceRef = jvm.invoke_virtual(&null_set, "comparator", "()Ljava/util/Comparator;", ()).await?; + let comparator: ClassInstanceRef = jvm + .invoke_virtual( + &null_set, + &null_set.class_definition().name(), + "comparator", + "()Ljava/util/Comparator;", + (), + ) + .await?; assert_eq!(comparator.identity(), nulls_first.identity()); let null_tail: ClassInstanceRef = jvm .invoke_virtual( &null_set, + &null_set.class_definition().name(), "tailSet", "(Ljava/lang/Object;)Ljava/util/SortedSet;", (ClassInstanceRef::::from(None),), ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&null_tail, "size", "()I", ()).await?, 2); - let first: ClassInstanceRef = jvm.invoke_virtual(&null_tail, "first", "()Ljava/lang/Object;", ()).await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&null_tail, &null_tail.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); + let first: ClassInstanceRef = jvm + .invoke_virtual(&null_tail, &null_tail.class_definition().name(), "first", "()Ljava/lang/Object;", ()) + .await?; assert!(first.is_null(), "null range bound must not be mistaken for an unbounded view"); Ok(()) } diff --git a/java_runtime/tests/classes/java/util/test_url.rs b/java_runtime/tests/classes/java/util/test_url.rs index 8d545ef9..f229c922 100644 --- a/java_runtime/tests/classes/java/util/test_url.rs +++ b/java_runtime/tests/classes/java/util/test_url.rs @@ -9,10 +9,16 @@ async fn test_file_url() -> Result<()> { let url_spec = JavaLangString::from_rust_string(&jvm, "file:test.txt").await?; let url = jvm.new_class("java/net/URL", "(Ljava/lang/String;)V", (url_spec,)).await?; - let protocol = jvm.invoke_virtual(&url, "getProtocol", "()Ljava/lang/String;", ()).await?; - let host = jvm.invoke_virtual(&url, "getHost", "()Ljava/lang/String;", ()).await?; - let port: i32 = jvm.invoke_virtual(&url, "getPort", "()I", ()).await?; - let file = jvm.invoke_virtual(&url, "getFile", "()Ljava/lang/String;", ()).await?; + let protocol = jvm + .invoke_virtual(&url, &url.class_definition().name(), "getProtocol", "()Ljava/lang/String;", ()) + .await?; + let host = jvm + .invoke_virtual(&url, &url.class_definition().name(), "getHost", "()Ljava/lang/String;", ()) + .await?; + let port: i32 = jvm.invoke_virtual(&url, &url.class_definition().name(), "getPort", "()I", ()).await?; + let file = jvm + .invoke_virtual(&url, &url.class_definition().name(), "getFile", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &protocol).await?, "file"); assert_eq!(port, -1); diff --git a/java_runtime/tests/classes/java/util/test_vector.rs b/java_runtime/tests/classes/java/util/test_vector.rs index 411ce018..7d386426 100644 --- a/java_runtime/tests/classes/java/util/test_vector.rs +++ b/java_runtime/tests/classes/java/util/test_vector.rs @@ -9,7 +9,9 @@ async fn assert_index_out_of_bounds_message(jvm: &Jvm, result: Result, exp }; assert!(jvm.is_instance(&*exception, "java/lang/IndexOutOfBoundsException")); - let exception_string: ClassInstanceRef = jvm.invoke_virtual(&exception, "toString", "()Ljava/lang/String;", ()).await?; + let exception_string: ClassInstanceRef = jvm + .invoke_virtual(&exception, &exception.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!( JavaLangString::to_rust_string(jvm, &exception_string).await?, format!("java.lang.IndexOutOfBoundsException: {expected_message}") @@ -24,41 +26,93 @@ async fn test_vector_cldc_legacy_api() -> Result<()> { let vector = jvm.new_class("java/util/Vector", "(II)V", (2, 3)).await?; let first = JavaLangString::from_rust_string(&jvm, "first").await?; let second = JavaLangString::from_rust_string(&jvm, "second").await?; - let _: () = jvm.invoke_virtual(&vector, "addElement", "(Ljava/lang/Object;)V", (first,)).await?; let _: () = jvm - .invoke_virtual(&vector, "addElement", "(Ljava/lang/Object;)V", (second.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "addElement", + "(Ljava/lang/Object;)V", + (first,), + ) + .await?; + let _: () = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "addElement", + "(Ljava/lang/Object;)V", + (second.clone(),), + ) .await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&vector, "capacity", "()I", ()).await?, 2); - let _: () = jvm.invoke_virtual(&vector, "ensureCapacity", "(I)V", (5,)).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&vector, "capacity", "()I", ()).await?, 5); assert_eq!( - jvm.invoke_virtual::<_, i32>(&vector, "indexOf", "(Ljava/lang/Object;I)I", (second, 1)) + jvm.invoke_virtual::<_, i32>(&vector, &vector.class_definition().name(), "capacity", "()I", ()) .await?, + 2 + ); + let _: () = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "ensureCapacity", "(I)V", (5,)) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&vector, &vector.class_definition().name(), "capacity", "()I", ()) + .await?, + 5 + ); + assert_eq!( + jvm.invoke_virtual::<_, i32>( + &vector, + &vector.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;I)I", + (second, 1) + ) + .await?, 1 ); let destination: ClassInstanceRef> = jvm.instantiate_array("Ljava/lang/Object;", 2).await?.into(); let _: () = jvm - .invoke_virtual(&vector, "copyInto", "([Ljava/lang/Object;)V", (destination.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "copyInto", + "([Ljava/lang/Object;)V", + (destination.clone(),), + ) .await?; let copied: Vec> = jvm.load_array(&destination, 0, 2).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &copied[0]).await?, "first"); assert_eq!(JavaLangString::to_rust_string(&jvm, &copied[1]).await?, "second"); - let elements: ClassInstanceRef = jvm.invoke_virtual(&vector, "elements", "()Ljava/util/Enumeration;", ()).await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&elements, "nextElement", "()Ljava/lang/Object;", ()).await?; + let elements: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "elements", "()Ljava/util/Enumeration;", ()) + .await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&elements, &elements.class_definition().name(), "nextElement", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "first"); let replacement = JavaLangString::from_rust_string(&jvm, "replacement").await?; let _: () = jvm - .invoke_virtual(&vector, "setElementAt", "(Ljava/lang/Object;I)V", (replacement, 1)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "setElementAt", + "(Ljava/lang/Object;I)V", + (replacement, 1), + ) + .await?; + let last: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "lastElement", "()Ljava/lang/Object;", ()) .await?; - let last: ClassInstanceRef = jvm.invoke_virtual(&vector, "lastElement", "()Ljava/lang/Object;", ()).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &last).await?, "replacement"); - let _: () = jvm.invoke_virtual(&vector, "setSize", "(I)V", (4,)).await?; - let text: ClassInstanceRef = jvm.invoke_virtual(&vector, "toString", "()Ljava/lang/String;", ()).await?; + let _: () = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "setSize", "(I)V", (4,)) + .await?; + let text: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "toString", "()Ljava/lang/String;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &text).await?, "[first, replacement, null, null]"); let result = jvm.new_class("java/util/Vector", "(I)V", (-1,)).await; @@ -76,33 +130,59 @@ async fn test_vector() -> Result<()> { let vector = jvm.new_class("java/util/Vector", "()V", ()).await?; - let is_empty: bool = jvm.invoke_virtual(&vector, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(is_empty); let element1 = JavaLangString::from_rust_string(&jvm, "testValue1").await?; let element2 = JavaLangString::from_rust_string(&jvm, "testValue2").await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element1.clone(),)).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element2.clone(),)).await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element1.clone(),), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element2.clone(),), + ) + .await?; - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 2); - let element_at1: ClassInstanceRef = jvm.invoke_virtual(&vector, "elementAt", "(I)Ljava/lang/Object;", (0,)).await?; + let element_at1: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "elementAt", "(I)Ljava/lang/Object;", (0,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &element_at1).await?, "testValue1"); - let is_empty: bool = jvm.invoke_virtual(&vector, "isEmpty", "()Z", ()).await?; + let is_empty: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "isEmpty", "()Z", ()) + .await?; assert!(!is_empty); - let removed: ClassInstanceRef = jvm.invoke_virtual(&vector, "remove", "(I)Ljava/lang/Object;", (0,)).await?; + let removed: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "remove", "(I)Ljava/lang/Object;", (0,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &removed).await?, "testValue1"); - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 1); - let _: () = jvm.invoke_virtual(&vector, "removeElementAt", "(I)V", (0,)).await?; + let _: () = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "removeElementAt", "(I)V", (0,)) + .await?; - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 0); Ok(()) @@ -114,12 +194,16 @@ async fn test_vector_null() -> Result<()> { let vector = jvm.new_class("java/util/Vector", "()V", ()).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (None,)).await?; + let _: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (None,)) + .await?; - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 1); - let element_at: ClassInstanceRef = jvm.invoke_virtual(&vector, "elementAt", "(I)Ljava/lang/Object;", (0,)).await?; + let element_at: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "elementAt", "(I)Ljava/lang/Object;", (0,)) + .await?; assert!(element_at.is_null()); Ok(()) @@ -135,61 +219,161 @@ async fn test_vector_index_of() -> Result<()> { let element2 = JavaLangString::from_rust_string(&jvm, "testValue2").await?; let element3 = JavaLangString::from_rust_string(&jvm, "testValue3").await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element1.clone(),)).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element2.clone(),)).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element3.clone(),)).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element2.clone(),)).await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element1.clone(),), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element2.clone(),), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element3.clone(),), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element2.clone(),), + ) + .await?; let index: i32 = jvm - .invoke_virtual(&vector, "lastIndexOf", "(Ljava/lang/Object;)I", (element2.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/Object;)I", + (element2.clone(),), + ) .await?; assert_eq!(index, 3); let index: i32 = jvm - .invoke_virtual(&vector, "lastIndexOf", "(Ljava/lang/Object;)I", (element1.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/Object;)I", + (element1.clone(),), + ) .await?; assert_eq!(index, 0); let non_existing_element = JavaLangString::from_rust_string(&jvm, "nonExisting").await?; let index: i32 = jvm - .invoke_virtual(&vector, "lastIndexOf", "(Ljava/lang/Object;)I", (non_existing_element,)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/Object;)I", + (non_existing_element,), + ) .await?; assert_eq!(index, -1); let index: i32 = jvm - .invoke_virtual(&vector, "lastIndexOf", "(Ljava/lang/Object;I)I", (element2.clone(), 2)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/Object;I)I", + (element2.clone(), 2), + ) .await?; assert_eq!(index, 1); - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (None,)).await?; - let index: i32 = jvm.invoke_virtual(&vector, "lastIndexOf", "(Ljava/lang/Object;)I", (None,)).await?; + let _: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (None,)) + .await?; + let index: i32 = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/Object;)I", + (None,), + ) + .await?; assert_eq!(index, 4); - let index: i32 = jvm.invoke_virtual(&vector, "indexOf", "(Ljava/lang/Object;)I", (element2,)).await?; + let index: i32 = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (element2,), + ) + .await?; assert_eq!(index, 1); let element2_same_value = JavaLangString::from_rust_string(&jvm, "testValue2").await?; let index: i32 = jvm - .invoke_virtual(&vector, "indexOf", "(Ljava/lang/Object;)I", (element2_same_value.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (element2_same_value.clone(),), + ) .await?; assert_eq!(index, 1); let index: i32 = jvm - .invoke_virtual(&vector, "lastIndexOf", "(Ljava/lang/Object;)I", (element2_same_value,)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/Object;)I", + (element2_same_value,), + ) .await?; assert_eq!(index, 3); - let index: i32 = jvm.invoke_virtual(&vector, "indexOf", "(Ljava/lang/Object;)I", (None,)).await?; + let index: i32 = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "indexOf", "(Ljava/lang/Object;)I", (None,)) + .await?; assert_eq!(index, 4); let non_existing_element = JavaLangString::from_rust_string(&jvm, "nonExisting").await?; let index: i32 = jvm - .invoke_virtual(&vector, "indexOf", "(Ljava/lang/Object;)I", (non_existing_element.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (non_existing_element.clone(),), + ) .await?; assert_eq!(index, -1); let index: i32 = jvm - .invoke_virtual(&vector, "lastIndexOf", "(Ljava/lang/Object;)I", (non_existing_element,)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "lastIndexOf", + "(Ljava/lang/Object;)I", + (non_existing_element,), + ) .await?; assert_eq!(index, -1); @@ -206,33 +390,75 @@ async fn test_vector_remove_element() -> Result<()> { let element2 = JavaLangString::from_rust_string(&jvm, "testValue2").await?; let element3 = JavaLangString::from_rust_string(&jvm, "testValue3").await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element1.clone(),)).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element2.clone(),)).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element3.clone(),)).await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element1.clone(),), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element2.clone(),), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (element3.clone(),), + ) + .await?; - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 3); let removed: bool = jvm - .invoke_virtual(&vector, "removeElement", "(Ljava/lang/Object;)Z", (element2.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "removeElement", + "(Ljava/lang/Object;)Z", + (element2.clone(),), + ) .await?; assert!(removed); - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 2); let index: i32 = jvm - .invoke_virtual(&vector, "indexOf", "(Ljava/lang/Object;)I", (element2.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (element2.clone(),), + ) .await?; assert_eq!(index, -1); let non_existing = JavaLangString::from_rust_string(&jvm, "nonExisting").await?; let removed: bool = jvm - .invoke_virtual(&vector, "removeElement", "(Ljava/lang/Object;)Z", (non_existing,)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "removeElement", + "(Ljava/lang/Object;)Z", + (non_existing,), + ) .await?; assert!(!removed); - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 2); Ok(()) @@ -247,17 +473,33 @@ async fn test_vector_remove_element_uses_java_equals() -> Result<()> { let element = JavaLangString::from_rust_string(&jvm, "sameValue").await?; let equal_element = JavaLangString::from_rust_string(&jvm, "sameValue").await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element,)).await?; + let _: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (element,)) + .await?; let contains: bool = jvm - .invoke_virtual(&vector, "contains", "(Ljava/lang/Object;)Z", (equal_element.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (equal_element.clone(),), + ) .await?; assert!(contains); - let removed: bool = jvm.invoke_virtual(&vector, "remove", "(Ljava/lang/Object;)Z", (equal_element,)).await?; + let removed: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (equal_element,), + ) + .await?; assert!(removed); - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 0); Ok(()) @@ -272,15 +514,23 @@ async fn test_vector_trim_to_size() -> Result<()> { let element1 = JavaLangString::from_rust_string(&jvm, "testValue1").await?; let element2 = JavaLangString::from_rust_string(&jvm, "testValue2").await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element1,)).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element2,)).await?; + let _: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (element1,)) + .await?; + let _: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (element2,)) + .await?; - let _: () = jvm.invoke_virtual(&vector, "trimToSize", "()V", ()).await?; + let _: () = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "trimToSize", "()V", ()) + .await?; - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 2); - let element_at: ClassInstanceRef = jvm.invoke_virtual(&vector, "elementAt", "(I)Ljava/lang/Object;", (0,)).await?; + let element_at: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "elementAt", "(I)Ljava/lang/Object;", (0,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &element_at).await?, "testValue1"); Ok(()) @@ -292,7 +542,9 @@ async fn test_first_element_empty() -> Result<()> { let vector = jvm.new_class("java/util/Vector", "()V", ()).await?; - let result: Result> = jvm.invoke_virtual(&vector, "firstElement", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "firstElement", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); @@ -309,13 +561,27 @@ async fn test_index_of_null() -> Result<()> { let vector = jvm.new_class("java/util/Vector", "()V", ()).await?; let element = JavaLangString::from_rust_string(&jvm, "testValue").await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (element,)).await?; let _: bool = jvm - .invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (JavaValue::Object(None),)) + .invoke_virtual(&vector, &vector.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (element,)) + .await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (JavaValue::Object(None),), + ) .await?; let index: i32 = jvm - .invoke_virtual(&vector, "indexOf", "(Ljava/lang/Object;)I", (JavaValue::Object(None),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "indexOf", + "(Ljava/lang/Object;)I", + (JavaValue::Object(None),), + ) .await?; assert_eq!(index, 1); @@ -366,48 +632,124 @@ async fn test_vector_collection_and_list_wrappers() -> Result<()> { let middle = JavaLangString::from_rust_string(&jvm, "middle").await?; let missing = JavaLangString::from_rust_string(&jvm, "missing").await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (first.clone(),)).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (second.clone(),)).await?; - let _: () = jvm.invoke_virtual(&vector, "add", "(ILjava/lang/Object;)V", (1, middle.clone())).await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (first.clone(),), + ) + .await?; + let _: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(Ljava/lang/Object;)Z", + (second.clone(),), + ) + .await?; + let _: () = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(ILjava/lang/Object;)V", + (1, middle.clone()), + ) + .await?; - let result: Result<()> = jvm.invoke_virtual(&vector, "add", "(ILjava/lang/Object;)V", (-1, middle.clone())).await; + let result: Result<()> = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(ILjava/lang/Object;)V", + (-1, middle.clone()), + ) + .await; assert_index_out_of_bounds_message(&jvm, result, "Index: -1, Size: 3").await?; - let result: Result<()> = jvm.invoke_virtual(&vector, "add", "(ILjava/lang/Object;)V", (4, middle.clone())).await; + let result: Result<()> = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "add", + "(ILjava/lang/Object;)V", + (4, middle.clone()), + ) + .await; assert_index_out_of_bounds_message(&jvm, result, "Index: 4, Size: 3").await?; - let value: ClassInstanceRef = jvm.invoke_virtual(&vector, "get", "(I)Ljava/lang/Object;", (1,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "get", "(I)Ljava/lang/Object;", (1,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "middle"); - let value: ClassInstanceRef = jvm.invoke_virtual(&vector, "get", "(I)Ljava/lang/Object;", (2,)).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "get", "(I)Ljava/lang/Object;", (2,)) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "second"); let contains: bool = jvm - .invoke_virtual(&vector, "contains", "(Ljava/lang/Object;)Z", (middle.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (middle.clone(),), + ) .await?; assert!(contains); let contains: bool = jvm - .invoke_virtual(&vector, "contains", "(Ljava/lang/Object;)Z", (missing.clone(),)) + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "contains", + "(Ljava/lang/Object;)Z", + (missing.clone(),), + ) .await?; assert!(!contains); - let removed: bool = jvm.invoke_virtual(&vector, "remove", "(Ljava/lang/Object;)Z", (middle.clone(),)).await?; + let removed: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (middle.clone(),), + ) + .await?; assert!(removed); - let removed: bool = jvm.invoke_virtual(&vector, "remove", "(Ljava/lang/Object;)Z", (missing.clone(),)).await?; + let removed: bool = jvm + .invoke_virtual( + &vector, + &vector.class_definition().name(), + "remove", + "(Ljava/lang/Object;)Z", + (missing.clone(),), + ) + .await?; assert!(!removed); - let array: ClassInstanceRef> = jvm.invoke_virtual(&vector, "toArray", "()[Ljava/lang/Object;", ()).await?; + let array: ClassInstanceRef> = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; assert_eq!(jvm.array_length(&array).await?, 2); let values: Vec> = jvm.load_array(&array, 0, 2).await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &values[0]).await?, "first"); assert_eq!(JavaLangString::to_rust_string(&jvm, &values[1]).await?, "second"); - let _: () = jvm.invoke_virtual(&vector, "clear", "()V", ()).await?; - let size: i32 = jvm.invoke_virtual(&vector, "size", "()I", ()).await?; + let _: () = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "clear", "()V", ()).await?; + let size: i32 = jvm.invoke_virtual(&vector, &vector.class_definition().name(), "size", "()I", ()).await?; assert_eq!(size, 0); - let array: ClassInstanceRef> = jvm.invoke_virtual(&vector, "toArray", "()[Ljava/lang/Object;", ()).await?; + let array: ClassInstanceRef> = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "toArray", "()[Ljava/lang/Object;", ()) + .await?; assert_eq!(jvm.array_length(&array).await?, 0); Ok(()) @@ -421,51 +763,97 @@ async fn test_vector_itr_is_live_and_remove_writes_through() -> Result<()> { let first = JavaLangString::from_rust_string(&jvm, "first").await?; let second = JavaLangString::from_rust_string(&jvm, "second").await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (first,)).await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (second,)).await?; + let _: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (first,)) + .await?; + let _: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (second,)) + .await?; - let iterator: ClassInstanceRef = jvm.invoke_virtual(&vector, "iterator", "()Ljava/util/Iterator;", ()).await?; + let iterator: ClassInstanceRef = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "iterator", "()Ljava/util/Iterator;", ()) + .await?; assert!(jvm.is_instance(&**iterator, "java/util/Iterator")); let third = JavaLangString::from_rust_string(&jvm, "third").await?; - let _: bool = jvm.invoke_virtual(&vector, "add", "(Ljava/lang/Object;)Z", (third,)).await?; + let _: bool = jvm + .invoke_virtual(&vector, &vector.class_definition().name(), "add", "(Ljava/lang/Object;)Z", (third,)) + .await?; - let has_next: bool = jvm.invoke_virtual(&iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; assert!(has_next); - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "first"); - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "second"); - let has_next: bool = jvm.invoke_virtual(&iterator, "hasNext", "()Z", ()).await?; + let has_next: bool = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; assert!(has_next); - let value: ClassInstanceRef = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await?; + let value: ClassInstanceRef = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "third"); - let _: () = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await?; - assert_eq!(jvm.invoke_virtual::<_, i32>(&vector, "size", "()I", ()).await?, 2); + let _: () = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await?; + assert_eq!( + jvm.invoke_virtual::<_, i32>(&vector, &vector.class_definition().name(), "size", "()I", ()) + .await?, + 2 + ); - let result: Result> = jvm.invoke_virtual(&iterator, "next", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "next", "()Ljava/lang/Object;", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; assert!(jvm.is_instance(&*exception, "java/util/NoSuchElementException")); - let result: Result<()> = jvm.invoke_virtual(&iterator, "remove", "()V", ()).await; + let result: Result<()> = jvm + .invoke_virtual(&iterator, &iterator.class_definition().name(), "remove", "()V", ()) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; assert!(jvm.is_instance(&*exception, "java/lang/IllegalStateException")); let empty_vector = jvm.new_class("java/util/Vector", "()V", ()).await?; - let empty_iterator: ClassInstanceRef = jvm.invoke_virtual(&empty_vector, "iterator", "()Ljava/util/Iterator;", ()).await?; - let has_next: bool = jvm.invoke_virtual(&empty_iterator, "hasNext", "()Z", ()).await?; + let empty_iterator: ClassInstanceRef = jvm + .invoke_virtual( + &empty_vector, + &empty_vector.class_definition().name(), + "iterator", + "()Ljava/util/Iterator;", + (), + ) + .await?; + let has_next: bool = jvm + .invoke_virtual(&empty_iterator, &empty_iterator.class_definition().name(), "hasNext", "()Z", ()) + .await?; assert!(!has_next); - let result: Result> = jvm.invoke_virtual(&empty_iterator, "next", "()Ljava/lang/Object;", ()).await; + let result: Result> = jvm + .invoke_virtual( + &empty_iterator, + &empty_iterator.class_definition().name(), + "next", + "()Ljava/lang/Object;", + (), + ) + .await; let Err(JavaError::JavaException(exception)) = result else { panic!("Expected JavaException, got {:?}", result); }; diff --git a/java_runtime/tests/classes/java/util/zip/test_zip_file.rs b/java_runtime/tests/classes/java/util/zip/test_zip_file.rs index 216559d9..bb7b5cff 100644 --- a/java_runtime/tests/classes/java/util/zip/test_zip_file.rs +++ b/java_runtime/tests/classes/java/util/zip/test_zip_file.rs @@ -16,17 +16,31 @@ async fn test_zip_entry() -> Result<()> { let entry_name = JavaLangString::from_rust_string(&jvm, "test.txt").await?; let entry = jvm - .invoke_virtual(&zip, "getEntry", "(Ljava/lang/String;)Ljava/util/zip/ZipEntry;", (entry_name,)) + .invoke_virtual( + &zip, + &zip.class_definition().name(), + "getEntry", + "(Ljava/lang/String;)Ljava/util/zip/ZipEntry;", + (entry_name,), + ) .await?; - let size: i64 = jvm.invoke_virtual(&entry, "getSize", "()J", ()).await?; + let size: i64 = jvm.invoke_virtual(&entry, &entry.class_definition().name(), "getSize", "()J", ()).await?; let is = jvm - .invoke_virtual(&zip, "getInputStream", "(Ljava/util/zip/ZipEntry;)Ljava/io/InputStream;", (entry,)) + .invoke_virtual( + &zip, + &zip.class_definition().name(), + "getInputStream", + "(Ljava/util/zip/ZipEntry;)Ljava/io/InputStream;", + (entry,), + ) .await?; let buf = jvm.instantiate_array("B", size as _).await?; - let _: i32 = jvm.invoke_virtual(&is, "read", "([B)I", (buf.clone(),)).await?; + let _: i32 = jvm + .invoke_virtual(&is, &is.class_definition().name(), "read", "([B)I", (buf.clone(),)) + .await?; let mut data = vec![0; size as _]; jvm.array_raw_buffer(&buf).await?.read(0, &mut data).unwrap(); diff --git a/java_runtime/tests/classes/org/rustjava/lang/test_rust_jar_class_loader.rs b/java_runtime/tests/classes/org/rustjava/lang/test_rust_jar_class_loader.rs index 7fba93af..607416bf 100644 --- a/java_runtime/tests/classes/org/rustjava/lang/test_rust_jar_class_loader.rs +++ b/java_runtime/tests/classes/org/rustjava/lang/test_rust_jar_class_loader.rs @@ -26,7 +26,13 @@ async fn test_find_class_uses_rustjar_runtime_source() -> Result<()> { let name = JavaLangString::from_rust_string(&jvm, "java/util/Random").await?; let class: ClassInstanceRef = jvm - .invoke_virtual(&class_loader, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;", (name,)) + .invoke_virtual( + &class_loader, + "org/rustjava/lang/RustJarClassLoader", + "findClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (name,), + ) .await?; assert!(!class.is_null()); diff --git a/java_runtime/tests/classes/org/rustjava/net/test_file_url_connection.rs b/java_runtime/tests/classes/org/rustjava/net/test_file_url_connection.rs index c20edabb..2e1af12e 100644 --- a/java_runtime/tests/classes/org/rustjava/net/test_file_url_connection.rs +++ b/java_runtime/tests/classes/org/rustjava/net/test_file_url_connection.rs @@ -12,10 +12,14 @@ async fn test_file_url() -> Result<()> { let url_spec = JavaLangString::from_rust_string(&jvm, "file:test.txt").await?; let url = jvm.new_class("java/net/URL", "(Ljava/lang/String;)V", (url_spec,)).await?; - let stream = jvm.invoke_virtual(&url, "openStream", "()Ljava/io/InputStream;", ()).await?; + let stream = jvm + .invoke_virtual(&url, &url.class_definition().name(), "openStream", "()Ljava/io/InputStream;", ()) + .await?; let buf = jvm.instantiate_array("B", 17).await?; - let len: i32 = jvm.invoke_virtual(&stream, "read", "([B)I", (buf.clone(),)).await?; + let len: i32 = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([B)I", (buf.clone(),)) + .await?; let mut data = vec![0; len as usize]; jvm.array_raw_buffer(&buf).await?.read(0, &mut data).unwrap(); diff --git a/java_runtime/tests/classes/org/rustjava/net/test_jar_url_connection.rs b/java_runtime/tests/classes/org/rustjava/net/test_jar_url_connection.rs index 193f07c6..54fb4b3d 100644 --- a/java_runtime/tests/classes/org/rustjava/net/test_jar_url_connection.rs +++ b/java_runtime/tests/classes/org/rustjava/net/test_jar_url_connection.rs @@ -14,12 +14,24 @@ async fn test_jar_entry() -> Result<()> { let url_spec = JavaLangString::from_rust_string(&jvm, "jar:file:test.jar!/test.txt").await?; let url = jvm.new_class("java/net/URL", "(Ljava/lang/String;)V", (url_spec,)).await?; - let connection = jvm.invoke_virtual(&url, "openConnection", "()Ljava/net/URLConnection;", ()).await?; + let connection = jvm + .invoke_virtual(&url, &url.class_definition().name(), "openConnection", "()Ljava/net/URLConnection;", ()) + .await?; - let stream = jvm.invoke_virtual(&connection, "getInputStream", "()Ljava/io/InputStream;", ()).await?; + let stream = jvm + .invoke_virtual( + &connection, + &connection.class_definition().name(), + "getInputStream", + "()Ljava/io/InputStream;", + (), + ) + .await?; let buf = jvm.instantiate_array("B", 17).await?; - let len: i32 = jvm.invoke_virtual(&stream, "read", "([B)I", (buf.clone(),)).await?; + let len: i32 = jvm + .invoke_virtual(&stream, &stream.class_definition().name(), "read", "([B)I", (buf.clone(),)) + .await?; let mut data = vec![0; len as usize]; jvm.array_raw_buffer(&buf).await?.read(0, &mut data).unwrap(); @@ -38,15 +50,29 @@ async fn test_jar_file() -> Result<()> { let url_spec = JavaLangString::from_rust_string(&jvm, "jar:file:test.jar!/").await?; let url = jvm.new_class("java/net/URL", "(Ljava/lang/String;)V", (url_spec,)).await?; - let connection = jvm.invoke_virtual(&url, "openConnection", "()Ljava/net/URLConnection;", ()).await?; + let connection = jvm + .invoke_virtual(&url, &url.class_definition().name(), "openConnection", "()Ljava/net/URLConnection;", ()) + .await?; let attributes = jvm - .invoke_virtual(&connection, "getMainAttributes", "()Ljava/util/jar/Attributes;", ()) + .invoke_virtual( + &connection, + &connection.class_definition().name(), + "getMainAttributes", + "()Ljava/util/jar/Attributes;", + (), + ) .await?; let key = JavaLangString::from_rust_string(&jvm, "Main-Class").await?; let value = jvm - .invoke_virtual(&attributes, "getValue", "(Ljava/lang/String;)Ljava/lang/String;", (key,)) + .invoke_virtual( + &attributes, + &attributes.class_definition().name(), + "getValue", + "(Ljava/lang/String;)Ljava/lang/String;", + (key,), + ) .await?; assert_eq!(JavaLangString::to_rust_string(&jvm, &value).await?, "JarTest"); @@ -63,12 +89,38 @@ async fn test_jar_cache() -> Result<()> { let url_spec = JavaLangString::from_rust_string(&jvm, "jar:file:test.jar!/").await?; let url = jvm.new_class("java/net/URL", "(Ljava/lang/String;)V", (url_spec,)).await?; - let connection = jvm.invoke_virtual(&url, "openConnection", "()Ljava/net/URLConnection;", ()).await?; + let connection = jvm + .invoke_virtual(&url, &url.class_definition().name(), "openConnection", "()Ljava/net/URLConnection;", ()) + .await?; - let jar_file = jvm.invoke_virtual(&connection, "getJarFile", "()Ljava/util/jar/JarFile;", ()).await?; - let jar_file2: ClassInstanceRef = jvm.invoke_virtual(&connection, "getJarFile", "()Ljava/util/jar/JarFile;", ()).await?; + let jar_file = jvm + .invoke_virtual( + &connection, + &connection.class_definition().name(), + "getJarFile", + "()Ljava/util/jar/JarFile;", + (), + ) + .await?; + let jar_file2: ClassInstanceRef = jvm + .invoke_virtual( + &connection, + &connection.class_definition().name(), + "getJarFile", + "()Ljava/util/jar/JarFile;", + (), + ) + .await?; - let equals: bool = jvm.invoke_virtual(&jar_file, "equals", "(Ljava/lang/Object;)Z", (jar_file2,)).await?; + let equals: bool = jvm + .invoke_virtual( + &jar_file, + &jar_file.class_definition().name(), + "equals", + "(Ljava/lang/Object;)Z", + (jar_file2,), + ) + .await?; assert!(equals); diff --git a/jvm/src/class_loader.rs b/jvm/src/class_loader.rs index aa739938..a86f978e 100644 --- a/jvm/src/class_loader.rs +++ b/jvm/src/class_loader.rs @@ -38,14 +38,20 @@ struct ClassInitialization { pub struct Class { pub definition: Box, java_class: Arc>>>, + defining_loader: Option>, initialization: Arc, } impl Class { - pub fn new(definition: Box, java_class: Option>) -> Self { + pub fn new( + definition: Box, + java_class: Option>, + defining_loader: Option>, + ) -> Self { Self { definition, java_class: Arc::new(RwLock::new(java_class)), + defining_loader, initialization: Arc::new(ClassInitialization { state: Mutex::new(ClassInitializationState { status: InitState::NotInitialized, @@ -89,6 +95,20 @@ impl Class { pub fn java_class(&self) -> Box { self.java_class.read().clone().unwrap() } + + pub(crate) fn is_same_runtime_package(&self, other: &Self) -> bool { + let package = self.definition.name(); + let other_package = other.definition.name(); + if package.rsplit_once('/').map_or("", |(package, _)| package) != other_package.rsplit_once('/').map_or("", |(package, _)| package) { + return false; + } + + match (&self.defining_loader, &other.defining_loader) { + (None, None) => true, + (Some(loader), Some(other_loader)) => loader.identity() == other_loader.identity(), + _ => false, + } + } } #[async_trait::async_trait] @@ -117,7 +137,7 @@ impl ClassLoaderWrapper for BootstrapClassLoaderWrapper<'_> { let definition = self.bootstrap_class_loader.load_class(jvm, name).await?; if let Some(definition) = definition { let java_class = JavaLangClass::from_rust_class(jvm, definition.clone(), None).await?; - let class = Class::new(definition, Some(java_class)); + let class = Class::new(definition, Some(java_class), None); jvm.register_class_internal(class.clone(), Some(self)).await?; Ok(Some(class)) @@ -144,7 +164,8 @@ impl ClassLoaderWrapper for JavaClassLoaderWrapper { if let Some(class) = class { let definition = JavaLangClass::to_rust_class(jvm, &class).await?; - Ok(Some(Class::new(definition, Some(class)))) + let defining_loader = JavaLangClass::class_loader(jvm, &class).await?; + Ok(Some(Class::new(definition, Some(class), defining_loader))) } else { Ok(None) } diff --git a/jvm/src/jvm.rs b/jvm/src/jvm.rs index f74603a8..a8dfecad 100644 --- a/jvm/src/jvm.rs +++ b/jvm/src/jvm.rs @@ -89,7 +89,7 @@ impl Jvm { ]; for class_name in bootstrap_classes.iter() { let class_definition = jvm.inner.bootstrap_class_loader.load_class(&jvm, class_name).await?.unwrap(); - let class = Class::new(class_definition, None); + let class = Class::new(class_definition, None, None); jvm.register_class_internal(class, None).await?; } @@ -342,33 +342,62 @@ impl Jvm { } } - pub async fn invoke_virtual(&self, instance: &Box, name: &str, descriptor: &str, args: T) -> Result + pub async fn invoke_virtual(&self, instance: &Box, class_name: &str, name: &str, descriptor: &str, args: T) -> Result where T: InvokeArg, U: From, { let args = args.into_arg(); - tracing::trace!("Invoke virtual {}.{name}:{descriptor}({args:?})", instance.class_definition().name()); + tracing::trace!("Invoke virtual {class_name}.{name}:{descriptor}({args:?})"); - let class = instance.class_definition(); - let method = self.find_virtual_method(&*class, name, descriptor, false)?; - if let Some(x) = method { - let args = iter::once(JavaValue::Object(Some(clone_box(&**instance)))) - .chain(args.into_vec()) - .collect::>(); + let owner = self.resolve_class(class_name).await?; + let Some((resolved_class, resolved_method)) = self.resolve_method(&owner, name, descriptor) else { + tracing::error!("No such method: {class_name}.{name}:{descriptor}"); + return Err(self + .exception("java/lang/NoSuchMethodError", &format!("{class_name}.{name}:{descriptor}")) + .await); + }; - let class = self.resolve_class(&class.name()).await?; // TODO we're resolving class twice - Ok(self - .execute_method(&class, Some(instance.clone()), &x, args.into_boxed_slice()) - .await? - .into()) - } else { - tracing::error!("No such method: {}.{name}:{descriptor}", class.name()); + if resolved_method.access_flags().contains(MethodAccessFlags::STATIC) { + return Err(self + .exception("java/lang/IncompatibleClassChangeError", &format!("{class_name}.{name}:{descriptor}")) + .await); + } - Err(self - .exception("java/lang/NoSuchMethodError", &format!("{}.{}:{}", class.name(), name, descriptor)) - .await) + let mut class = self.get_class(&instance.class_definition().name()); + let mut selected = None; + while let Some(candidate_class) = class { + if let Some(candidate_method) = candidate_class.definition.method(name, descriptor, false) + && self.method_overrides(&candidate_class, &candidate_method, &resolved_class, &resolved_method) + { + selected = Some((candidate_class, candidate_method)); + break; + } + + class = candidate_class + .definition + .super_class_name() + .and_then(|super_class| self.get_class(&super_class)); + } + + let Some((declaring_class, method)) = selected else { + return Err(self + .exception("java/lang/AbstractMethodError", &format!("{class_name}.{name}:{descriptor}")) + .await); + }; + if method.access_flags().contains(MethodAccessFlags::ABSTRACT) { + return Err(self + .exception("java/lang/AbstractMethodError", &format!("{class_name}.{name}:{descriptor}")) + .await); } + + let args = iter::once(JavaValue::Object(Some(clone_box(&**instance)))) + .chain(args.into_vec()) + .collect::>(); + Ok(self + .execute_method(&declaring_class, Some(instance.clone()), &method, args.into_boxed_slice()) + .await? + .into()) } // non-virtual @@ -831,7 +860,7 @@ impl Jvm { let java_class = Some(JavaLangClass::from_rust_class(self, class.clone(), class_loader.clone()).await?); - let class = Class::new(class, java_class.clone()); + let class = Class::new(class, java_class.clone(), class_loader.clone()); if let Some(x) = class_loader { self.register_class_internal(class, Some(&JavaClassLoaderWrapper::new(x))).await?; @@ -1176,19 +1205,35 @@ impl Jvm { self.resolve_field(&super_class, name, descriptor) } - // JVMS 5.4.3.3 method resolution: search the class, then its superclass (interfaces have no static methods - // in a 1.2 target). Matching is by name and descriptor only; the caller checks static-ness afterwards. + // JVMS 5.4.3.3 method resolution searches the class hierarchy before inherited interface methods. fn resolve_method(&self, class: &Class, name: &str, descriptor: &str) -> Option<(Class, Box)> { - if let Some(method) = class - .definition - .method(name, descriptor, true) - .or_else(|| class.definition.method(name, descriptor, false)) - { - return Some((class.clone(), method)); + let mut class = Some(class.clone()); + let mut interfaces = Vec::new(); + while let Some(candidate) = class { + if let Some(method) = candidate + .definition + .method(name, descriptor, true) + .or_else(|| candidate.definition.method(name, descriptor, false)) + { + return Some((candidate, method)); + } + + interfaces.extend(candidate.definition.interface_names()); + class = candidate + .definition + .super_class_name() + .and_then(|super_class| self.get_class(&super_class)); } - let super_class = self.get_class(&class.definition.super_class_name()?)?; - self.resolve_method(&super_class, name, descriptor) + while let Some(interface_name) = interfaces.pop() { + let interface = self.get_class(&interface_name)?; + if let Some(method) = interface.definition.method(name, descriptor, false) { + return Some((interface, method)); + } + interfaces.extend(interface.definition.interface_names()); + } + + None } pub(crate) fn find_field(&self, class: &dyn ClassDefinition, name: &str, descriptor: &str) -> Result>> { @@ -1204,19 +1249,59 @@ impl Jvm { } } - fn find_virtual_method(&self, class: &dyn ClassDefinition, name: &str, descriptor: &str, is_static: bool) -> Result>> { - let method = class.method(name, descriptor, false); + fn method_overrides( + &self, + candidate_class: &Class, + candidate_method: &Box, + resolved_class: &Class, + resolved_method: &Box, + ) -> bool { + if candidate_class.definition.name() == resolved_class.definition.name() { + return true; + } + if !self.is_inherited_from(&*candidate_class.definition, &resolved_class.definition.name()) + || candidate_method + .access_flags() + .intersects(MethodAccessFlags::PRIVATE | MethodAccessFlags::STATIC) + { + return false; + } + + let resolved_access = resolved_method.access_flags(); + if resolved_access.intersects(MethodAccessFlags::PUBLIC | MethodAccessFlags::PROTECTED) { + return true; + } + if resolved_access.contains(MethodAccessFlags::PRIVATE) { + return false; + } + if candidate_class.is_same_runtime_package(resolved_class) { + return true; + } - if let Some(x) = method { - if x.access_flags().contains(MethodAccessFlags::STATIC) == is_static { - return Ok(Some(x)); + // JVMS 5.4.5 also permits an override inherited through an intermediate method that overrides the package-private declaration. + let mut super_class = candidate_class + .definition + .super_class_name() + .and_then(|class_name| self.get_class(&class_name)); + while let Some(intermediate_class) = super_class { + if intermediate_class.definition.name() == resolved_class.definition.name() { + break; } - } else if let Some(x) = class.super_class_name() { - let super_class = self.inner.classes.read().get(&x).unwrap().definition.clone(); - return self.find_virtual_method(&*super_class, name, descriptor, is_static); + if let Some(intermediate_method) = intermediate_class + .definition + .method(&resolved_method.name(), &resolved_method.descriptor(), false) + && self.method_overrides(candidate_class, candidate_method, &intermediate_class, &intermediate_method) + && self.method_overrides(&intermediate_class, &intermediate_method, resolved_class, resolved_method) + { + return true; + } + super_class = intermediate_class + .definition + .super_class_name() + .and_then(|class_name| self.get_class(&class_name)); } - Ok(None) + false } async fn execute_method( diff --git a/jvm/src/runtime/java_io_input_stream.rs b/jvm/src/runtime/java_io_input_stream.rs index b38c35a0..88be98b3 100644 --- a/jvm/src/runtime/java_io_input_stream.rs +++ b/jvm/src/runtime/java_io_input_stream.rs @@ -14,7 +14,9 @@ impl JavaIoInputStream { let java_buffer = jvm.instantiate_array("B", 1024).await?; loop { - let bytes_read: i32 = jvm.invoke_virtual(this, "read", "([B)I", (java_buffer.clone(),)).await?; + let bytes_read: i32 = jvm + .invoke_virtual(this, "java/io/InputStream", "read", "([B)I", (java_buffer.clone(),)) + .await?; if bytes_read == 0 || bytes_read == -1 { break; diff --git a/jvm/src/runtime/java_lang_class_loader.rs b/jvm/src/runtime/java_lang_class_loader.rs index f9a53202..15913933 100644 --- a/jvm/src/runtime/java_lang_class_loader.rs +++ b/jvm/src/runtime/java_lang_class_loader.rs @@ -21,7 +21,13 @@ impl JavaLangClassLoader { let java_class_name = JavaLangString::from_rust_string(jvm, &binary_name).await?; let java_class: Option> = jvm - .invoke_virtual(this, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", (java_class_name,)) + .invoke_virtual( + this, + "java/lang/ClassLoader", + "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + (java_class_name,), + ) .await?; Ok(java_class) @@ -32,7 +38,13 @@ impl JavaLangClassLoader { let java_name = JavaLangString::from_rust_string(jvm, name).await?; let java_resource: Option> = jvm - .invoke_virtual(this, "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;", (java_name,)) + .invoke_virtual( + this, + "java/lang/ClassLoader", + "getResourceAsStream", + "(Ljava/lang/String;)Ljava/io/InputStream;", + (java_name,), + ) .await?; Ok(java_resource) diff --git a/jvm/tests/test_garbage_collection.rs b/jvm/tests/test_garbage_collection.rs index 6b367c21..c5621c39 100644 --- a/jvm/tests/test_garbage_collection.rs +++ b/jvm/tests/test_garbage_collection.rs @@ -60,6 +60,7 @@ async fn test_garbage_collection() -> JvmResult<()> { let _: () = jvm .invoke_virtual( &vector, + &vector.class_definition().name(), "addElement", "(Ljava/lang/Object;)V", (JavaLangString::from_rust_string(&jvm, "test").await?,), @@ -94,6 +95,7 @@ async fn test_garbage_collection_hashtable() -> JvmResult<()> { let _: JavaValue = jvm .invoke_virtual( &hashtable, + &hashtable.class_definition().name(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", (key.clone(), value.clone()), @@ -124,7 +126,9 @@ async fn substring_keeps_shared_array_alive_after_parent_collection() -> JvmResu jvm.push_native_frame(); let parent = JavaLangString::from_rust_string(&jvm, "HelloWorld").await?; - let child: ClassInstanceRef = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 5)).await?; + let child: ClassInstanceRef = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 5)) + .await?; let child = jvm.new_global_ref(&child).unwrap(); jvm.pop_frame(); @@ -217,7 +221,9 @@ async fn field_and_method_results_are_local_references() -> JvmResult<()> { jvm.push_native_frame(); let vector: ClassInstanceRef = jvm.new_class("java/util/Vector", "(I)V", (1,)).await?.into(); let object: ClassInstanceRef = jvm.new_class("java/lang/Object", "()V", ()).await?.into(); - let _: () = jvm.invoke_virtual(&vector, "addElement", "(Ljava/lang/Object;)V", (object,)).await?; + let _: () = jvm + .invoke_virtual(&vector, "java/util/Vector", "addElement", "(Ljava/lang/Object;)V", (object,)) + .await?; let vector = jvm.new_global_ref(&vector).unwrap(); jvm.pop_frame(); @@ -243,12 +249,16 @@ async fn field_and_method_results_are_local_references() -> JvmResult<()> { jvm.push_native_frame(); let vector: ClassInstanceRef = jvm.new_class("java/util/Vector", "(I)V", (1,)).await?.into(); let object: ClassInstanceRef = jvm.new_class("java/lang/Object", "()V", ()).await?.into(); - let _: () = jvm.invoke_virtual(&vector, "addElement", "(Ljava/lang/Object;)V", (object,)).await?; + let _: () = jvm + .invoke_virtual(&vector, "java/util/Vector", "addElement", "(Ljava/lang/Object;)V", (object,)) + .await?; let vector = jvm.new_global_ref(&vector).unwrap(); jvm.pop_frame(); jvm.push_native_frame(); - let _: ClassInstanceRef = jvm.invoke_virtual(&vector, "remove", "(I)Ljava/lang/Object;", (0,)).await?; + let _: ClassInstanceRef = jvm + .invoke_virtual(&vector, "java/util/Vector", "remove", "(I)Ljava/lang/Object;", (0,)) + .await?; assert_eq!(jvm.collect_garbage()?, 0); jvm.pop_frame(); @@ -288,7 +298,7 @@ async fn returned_exception_is_a_local_reference() -> JvmResult<()> { jvm.push_native_frame(); let vector: ClassInstanceRef = jvm.new_class("java/util/Vector", "()V", ()).await?.into(); let _: jvm::JavaError = jvm - .invoke_virtual::<_, ClassInstanceRef<()>>(&vector, "elementAt", "(I)Ljava/lang/Object;", (0,)) + .invoke_virtual::<_, ClassInstanceRef<()>>(&vector, "java/util/Vector", "elementAt", "(I)Ljava/lang/Object;", (0,)) .await .unwrap_err(); jvm.pop_frame(); @@ -297,7 +307,7 @@ async fn returned_exception_is_a_local_reference() -> JvmResult<()> { jvm.push_native_frame(); let vector: ClassInstanceRef = jvm.new_class("java/util/Vector", "()V", ()).await?.into(); let _: jvm::JavaError = jvm - .invoke_virtual::<_, ClassInstanceRef<()>>(&vector, "elementAt", "(I)Ljava/lang/Object;", (0,)) + .invoke_virtual::<_, ClassInstanceRef<()>>(&vector, "java/util/Vector", "elementAt", "(I)Ljava/lang/Object;", (0,)) .await .unwrap_err(); @@ -317,7 +327,7 @@ async fn thread_start_keeps_the_thread_alive_until_spawn_callback_runs() -> JvmR jvm.push_native_frame(); let thread = jvm.new_class("java/lang/Thread", "()V", ()).await?; - let _: () = jvm.invoke_virtual(&thread, "start", "()V", ()).await?; + let _: () = jvm.invoke_virtual(&thread, &thread.class_definition().name(), "start", "()V", ()).await?; jvm.pop_frame(); assert_eq!(jvm.collect_garbage()?, 0); diff --git a/jvm/tests/test_string.rs b/jvm/tests/test_string.rs index a8ed856f..9daccb08 100644 --- a/jvm/tests/test_string.rs +++ b/jvm/tests/test_string.rs @@ -38,7 +38,9 @@ async fn test_to_utf16_on_substring_preserves_unpaired_surrogate() -> Result<()> jvm.store_array(&mut chars, 0, [0x61 as JavaChar, 0xd800, 0x62]).await?; let string = jvm.new_class("java/lang/String", "([C)V", (chars,)).await?; - let sub = jvm.invoke_virtual(&string, "substring", "(II)Ljava/lang/String;", (1, 3)).await?; + let sub = jvm + .invoke_virtual(&string, &string.class_definition().name(), "substring", "(II)Ljava/lang/String;", (1, 3)) + .await?; assert_eq!(JavaLangString::to_utf16(&jvm, &sub).await?, [0xd800, 0x62]); @@ -50,14 +52,20 @@ async fn test_intern_on_substring_uses_logical_slice() -> Result<()> { let jvm = test_jvm().await?; let parent = JavaLangString::from_rust_string(&jvm, "xxHelloyy").await?; - let sub = jvm.invoke_virtual(&parent, "substring", "(II)Ljava/lang/String;", (2, 7)).await?; + let sub = jvm + .invoke_virtual(&parent, &parent.class_definition().name(), "substring", "(II)Ljava/lang/String;", (2, 7)) + .await?; - let interned: Box = jvm.invoke_virtual(&sub, "intern", "()Ljava/lang/String;", ()).await?; + let interned: Box = jvm + .invoke_virtual(&sub, &sub.class_definition().name(), "intern", "()Ljava/lang/String;", ()) + .await?; let pooled = jvm.intern_string("Hello").await?; assert!(interned == pooled); let independent = JavaLangString::from_rust_string(&jvm, "Hello").await?; - let independent_interned: Box = jvm.invoke_virtual(&independent, "intern", "()Ljava/lang/String;", ()).await?; + let independent_interned: Box = jvm + .invoke_virtual(&independent, &independent.class_definition().name(), "intern", "()Ljava/lang/String;", ()) + .await?; assert!(interned == independent_interned); Ok(()) diff --git a/jvm_rust/src/interpreter.rs b/jvm_rust/src/interpreter.rs index 43b822c6..ed9e21ef 100644 --- a/jvm_rust/src/interpreter.rs +++ b/jvm_rust/src/interpreter.rs @@ -642,7 +642,9 @@ impl Interpreter { .await); } - let result = jvm.invoke_virtual(&instance.unwrap(), &x.name, &x.descriptor, params).await?; + let instance = instance.unwrap(); + let class_name = instance.class_definition().name(); + let result = jvm.invoke_virtual(&instance, &class_name, &x.name, &x.descriptor, params).await?; Self::push_invoke_result(stack_frame, result); } Opcode::Invokespecial(x) => { @@ -683,7 +685,7 @@ impl Interpreter { .await); } - let result = jvm.invoke_virtual(&instance.unwrap(), &x.name, &x.descriptor, params).await?; + let result = jvm.invoke_virtual(&instance.unwrap(), &x.class, &x.name, &x.descriptor, params).await?; Self::push_invoke_result(stack_frame, result); } Opcode::Ior => { diff --git a/src/lib.rs b/src/lib.rs index 342ab98c..db8fed99 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,11 +31,14 @@ where .unwrap(); let _: () = jvm - .invoke_virtual(&x, "printStackTrace", "(Ljava/io/PrintWriter;)V", (print_writer,)) + .invoke_virtual(&x, "java/lang/Throwable", "printStackTrace", "(Ljava/io/PrintWriter;)V", (print_writer,)) .await .unwrap(); - let trace = jvm.invoke_virtual(&string_writer, "toString", "()Ljava/lang/String;", []).await.unwrap(); + let trace = jvm + .invoke_virtual(&string_writer, "java/io/StringWriter", "toString", "()Ljava/lang/String;", []) + .await + .unwrap(); Err(anyhow::anyhow!( "Java Exception:\n{}", @@ -101,14 +104,23 @@ async fn get_jar_main_class(jvm: &Jvm, jar_path: &Path) -> Result { let file = jvm.new_class("java/io/File", "(Ljava/lang/String;)V", (filename,)).await?; let jar_file = jvm.new_class("java/util/jar/JarFile", "(Ljava/io/File;)V", (file,)).await?; - let manifest = jvm.invoke_virtual(&jar_file, "getManifest", "()Ljava/util/jar/Manifest;", ()).await?; + let manifest = jvm + .invoke_virtual(&jar_file, "java/util/jar/JarFile", "getManifest", "()Ljava/util/jar/Manifest;", ()) + .await?; let attributes = jvm - .invoke_virtual(&manifest, "getMainAttributes", "()Ljava/util/jar/Attributes;", ()) + .invoke_virtual( + &manifest, + "java/util/jar/Manifest", + "getMainAttributes", + "()Ljava/util/jar/Attributes;", + (), + ) .await?; let main_class = jvm .invoke_virtual( &attributes, + "java/util/jar/Attributes", "getValue", "(Ljava/lang/String;)Ljava/lang/String;", (JavaLangString::from_rust_string(jvm, "Main-Class").await?,), diff --git a/test_data/VirtualDispatchSemantics.class b/test_data/VirtualDispatchSemantics.class new file mode 100644 index 0000000000000000000000000000000000000000..cb9a9d342e13763f8dde14e5c8c53b40845bc7f6 GIT binary patch literal 931 zcmZ`%TW=CU7(K&n%N7cii=a}a-ng`^7ksIv57yK+!IlI=VoWr{GNn`ZLY772ukknN z15G6H2l%6m-vDl_w)-&O+06OQoH_IT{Pq0@fF_>k2qCN?l0XzOhV%*l$PJ4-1LLrF zB21ql_Dnj`-)0C`s$C6B45hvt4Y_X~8%M4u|G?T@hCpDgp5y!S=XkN%N)0oxVBOPO6qwhWe!~p6iou(LdjnR$bZiUDEM| zcf?IGGWP$#eS2sLTR1-VrR(U(ARNb46f_hQxQ6S0#nbsb@`X*QxMK<_*O~<pc?oU&nvnB1}$vX$ywY4!vpBb@=s+{PUZcN4gW z`wW>2j$+V;>R`(uFO~l#s$Csb)HKu+*ic^911}dParns*9z)z63U3yMh6Y2SD?NYA ztrv^u?+BYazBET1#suqxHUhL6pkm|Bb6r8)0?BmIR7zhPH|uUCpSduc@DPum0etW+M64Zl$3#I4Pd^~u qNVv@EWM_rDo7`ECh`-Zb{K|IQ7_!^{Gj1~9(f)63)7s;@hl3y9hdJ{A literal 0 HcmV?d00001 diff --git a/test_data/dispatch/base/ProtectedBridge.class b/test_data/dispatch/base/ProtectedBridge.class new file mode 100644 index 0000000000000000000000000000000000000000..26a96567685c789862ec7c8f2a7ec7d0a41b488e GIT binary patch literal 321 zcmZ9Hy-EW?6ot>--?&B-C5=c5yF}1!>>?HkSOp10?C
    *%^0CbM}itpp1nz=x9D z30RmZ?m2Vjy9egy_v;(L4Nekx@M8pBgop@dgsmduZ<#WWoK=#98?IW> z!Du{x;SHx1*JZl2M%U$pkSv?lcj&q3E1E?!t=l6X7LD)Gzl zWbw{Bjxx^EXjK*_PwxofYF!nvelnKrFaLE;EsblO$r<)JkTUq9=kgnglel-Y2Yt&x cXo=c2;EJ}<5w+-0yiPBIuM^PXUCA8ujtECR_5c6? literal 0 HcmV?d00001 diff --git a/test_data/dispatch/base/SamePackageChild.class b/test_data/dispatch/base/SamePackageChild.class new file mode 100644 index 0000000000000000000000000000000000000000..1655e2b8fd362c07baa308e61342ba8ac274c8ef GIT binary patch literal 319 zcmZ8cO-sW-6r4?(q{eEi=s`rmTPtWT-jp6Jcq$@9yuTz%x|*gXAN^hSBzW)#_@l&G z^`I{7n|br*4ZH6juWtY@uoJ?88=%vJ2VdbJGxbuMbQUF2>*!9>C&~3Sxq^RXO4E!L z+~Me^YimbpG#ewzY>3deuS6ot=Cnxw{R8*wAjg}YYJ*|<|&Sm>&VP;oy=#&mR?k^JF%Kux#gkl1VWh3ZvaPkPE(z(&!p9`;#%^qA@0@F00(YzGtGhU^6xZ2)RfK^*`9 literal 0 HcmV?d00001 diff --git a/test_data/dispatch/foreign/ForeignProtectedGrandchild.class b/test_data/dispatch/foreign/ForeignProtectedGrandchild.class new file mode 100644 index 0000000000000000000000000000000000000000..c3c8924ce381a1547d6ea3c40184f1d2acafe4f7 GIT binary patch literal 354 zcmZ{fKTpFj5XGO9<`1DzK;2M<*jf-|VFNLMRF(=M6|p<9Ne>05a-DoGn2;Fw0DLIK zS%``S5AWxDes?E-e!YJHIKys+0AYe&9}!}Kk)qX7x^j^ha;5V-+c;f1t*$JoN(;mn zWXN3#gyYFWid0~@{LP#=E6s`=bvi*NaJ-)N*jP=K$)`VDPrcy=RW7Jj0=?@-@q)pO zjJ|E33vKUZQL__uvTm8f@nrTSJDJzgRQcRlGS#_2Hg8&6>M8l`!T%dheJ>8N!5{V~ w0FOq@y2;guDVWjG8^kML1p2K0nN8L$Y_t04KGVD5Uh=~D8%((xuoqzG8#Aj<+5i9m literal 0 HcmV?d00001 diff --git a/test_data/dispatch/foreign/ForeignPublicGrandchild.class b/test_data/dispatch/foreign/ForeignPublicGrandchild.class new file mode 100644 index 0000000000000000000000000000000000000000..75d576cbfef05e496cb6bf27dbd0660d58a8bb36 GIT binary patch literal 342 zcmZ{fJ5R$f6orqI=0PZwA|@UKTZ#l(x`7x#DocfsirAglq!$IJavr}6CL{)a06z+G zO(n#Fhx7R!pL-;Ke!YJHm|~p3gCAiqM1W9WUs1D?ZL!R9+34)9%PT6bEU8ipgcoF} zy%g}%$wQ1-V7&SXoVHe)hFa=%ghU|yZF#J%rqX1yHP?MNoL0q>DkU(ut`%30=4AA3 z_nd2cFY}6>pqEw0+)F3(C)vxalBUcSttC^Q3nYuWvxT0K%O3tyf94i(j1B&zJ07?f tA?qejM@+#CPTnA1`64i6b?Ee#@}Gf(}+C}JKypP& literal 0 HcmV?d00001 diff --git a/test_data/dispatch/interfaces/InheritedOperation.class b/test_data/dispatch/interfaces/InheritedOperation.class new file mode 100644 index 0000000000000000000000000000000000000000..96c3014380f32eb41d1906c35dae5890898aecc0 GIT binary patch literal 180 zcmX^0Z`VEs1_l!bPId++Mh3N%%;JK?lH?5i%)FA+qO`>1)M9%)E4KMh33n u{L-T2RJY8WR7M7IOr!Ncde|5l7#Wy>?qXnI1lq*Pzy@M5umedZ1`Yu4EHNSg literal 0 HcmV?d00001 diff --git a/test_data/dispatch/interfaces/InterfaceImplementation.class b/test_data/dispatch/interfaces/InterfaceImplementation.class new file mode 100644 index 0000000000000000000000000000000000000000..d877f985024095389d3b4025988fe0628cb1ca2e GIT binary patch literal 359 zcmaKnKTpFj5XIjmZPSKA%byJxU}`}$3tJHj5>llKh9Y)1Ia;H{iCh=H7EDMCd;mTa z;*6jY40w3&{QNuH_x|zv2H+H%F#?1UYHiffARK0TQ7M#@g`JvY4{H zQPW(KR#~zAhIV@W@x6LbNv_N+nK-M>Y)FVF<I#Ywz=^a6U8g3uQA$3Q5$jtx|)+v%gqJ`I3N}7Nm1h0sse|NX$p6EMyKJ~k-0v3LNA0_Sy zDTJ^vyR$Q}JLk*s1Yn3(hzh&_egjq12F4G Date: Sun, 16 Aug 2026 20:54:52 +0900 Subject: [PATCH 2/2] Complete runtime access flags --- .../java/io/byte_array_input_stream.rs | 41 ++++--- .../src/classes/java/io/data_input.rs | 30 ++--- .../src/classes/java/io/data_input_stream.rs | 74 +++++++++--- .../src/classes/java/io/data_output.rs | 42 ++++--- .../src/classes/java/io/data_output_stream.rs | 83 +++++++++++--- .../src/classes/java/io/eof_exception.rs | 7 +- java_runtime/src/classes/java/io/file.rs | 2 +- .../src/classes/java/io/file_descriptor.rs | 8 +- .../src/classes/java/io/file_input_stream.rs | 21 ++-- .../java/io/file_not_found_exception.rs | 7 +- .../src/classes/java/io/file_output_stream.rs | 16 +-- .../classes/java/io/input_stream_reader.rs | 27 ++--- .../java/io/interrupted_io_exception.rs | 8 +- .../src/classes/java/io/io_exception.rs | 7 +- .../classes/java/io/output_stream_writer.rs | 10 +- .../src/classes/java/io/random_access_file.rs | 8 +- .../src/classes/java/io/string_writer.rs | 8 +- .../java/io/unsupported_encoding_exception.rs | 7 +- .../java/io/utf_data_format_exception.rs | 7 +- .../java/lang/abstract_method_error.rs | 7 +- .../java/lang/abstract_string_builder.rs | 10 +- .../classes/java/lang/arithmetic_exception.rs | 7 +- .../array_index_out_of_bounds_exception.rs | 7 +- .../java/lang/array_store_exception.rs | 7 +- java_runtime/src/classes/java/lang/class.rs | 25 +++-- .../classes/java/lang/class_cast_exception.rs | 7 +- .../classes/java/lang/class_format_error.rs | 7 +- .../src/classes/java/lang/class_loader.rs | 6 +- .../java/lang/class_not_found_exception.rs | 7 +- .../lang/clone_not_supported_exception.rs | 7 +- java_runtime/src/classes/java/lang/error.rs | 7 +- .../src/classes/java/lang/exception.rs | 11 +- .../lang/exception_in_initializer_error.rs | 11 +- .../java/lang/illegal_access_exception.rs | 7 +- .../java/lang/illegal_argument_exception.rs | 7 +- .../lang/illegal_monitor_state_exception.rs | 7 +- .../lang/illegal_thread_state_exception.rs | 7 +- .../lang/incompatible_class_change_error.rs | 7 +- .../lang/index_out_of_bounds_exception.rs | 7 +- .../classes/java/lang/instantiation_error.rs | 7 +- .../java/lang/instantiation_exception.rs | 7 +- .../java/lang/interrupted_exception.rs | 7 +- .../src/classes/java/lang/linkage_error.rs | 7 +- .../lang/negative_array_size_exception.rs | 7 +- .../java/lang/no_class_def_found_error.rs | 7 +- .../classes/java/lang/no_such_field_error.rs | 7 +- .../classes/java/lang/no_such_method_error.rs | 7 +- .../java/lang/null_pointer_exception.rs | 7 +- .../java/lang/number_format_exception.rs | 7 +- java_runtime/src/classes/java/lang/object.rs | 4 +- .../classes/java/lang/out_of_memory_error.rs | 7 +- .../src/classes/java/lang/runnable.rs | 8 +- java_runtime/src/classes/java/lang/runtime.rs | 22 +++- .../classes/java/lang/runtime_exception.rs | 11 +- .../classes/java/lang/security_exception.rs | 7 +- java_runtime/src/classes/java/lang/string.rs | 106 +++++++++++------- .../string_index_out_of_bounds_exception.rs | 7 +- java_runtime/src/classes/java/lang/system.rs | 4 +- java_runtime/src/classes/java/lang/thread.rs | 2 +- .../src/classes/java/lang/throwable.rs | 8 +- .../java/lang/unsatisfied_link_error.rs | 7 +- .../lang/unsupported_class_version_error.rs | 7 +- .../lang/unsupported_operation_exception.rs | 7 +- .../src/classes/java/lang/verify_error.rs | 7 +- .../java/lang/virtual_machine_error.rs | 6 +- .../classes/java/net/jar_url_connection.rs | 6 +- .../java/net/malformed_url_exception.rs | 7 +- .../java/net/unknown_service_exception.rs | 7 +- java_runtime/src/classes/java/net/url.rs | 47 +++++--- .../src/classes/java/net/url_class_loader.rs | 6 +- .../src/classes/java/net/url_connection.rs | 6 +- .../src/classes/java/util/abstract_list.rs | 16 +-- .../java/util/abstract_list_sub_list.rs | 18 +-- .../src/classes/java/util/array_list.rs | 6 +- .../src/classes/java/util/array_list_itr.rs | 16 +-- .../classes/java/util/arrays_array_list.rs | 6 +- .../src/classes/java/util/calendar.rs | 10 +- .../java/util/collections_copies_list.rs | 2 +- .../java/util/collections_singleton_set.rs | 2 +- .../collections_unmodifiable_collection.rs | 6 +- ...ctions_unmodifiable_collection_iterator.rs | 6 +- .../util/collections_unmodifiable_list.rs | 6 +- .../collections_unmodifiable_list_iterator.rs | 6 +- .../java/util/collections_unmodifiable_map.rs | 6 +- .../collections_unmodifiable_map_entry.rs | 6 +- .../collections_unmodifiable_map_entry_set.rs | 6 +- ...ons_unmodifiable_map_entry_set_iterator.rs | 6 +- .../java/util/collections_unmodifiable_set.rs | 6 +- .../collections_unmodifiable_sorted_map.rs | 6 +- .../collections_unmodifiable_sorted_set.rs | 6 +- .../src/classes/java/util/dictionary.rs | 4 +- .../java/util/empty_stack_exception.rs | 7 +- .../src/classes/java/util/enumeration.rs | 10 +- .../src/classes/java/util/hash_map.rs | 34 ++++-- .../src/classes/java/util/hash_map_entry.rs | 18 +-- .../java/util/hash_map_entry_iterator.rs | 10 +- .../classes/java/util/hash_map_entry_set.rs | 28 +++-- .../java/util/hash_map_hash_iterator.rs | 14 +-- .../java/util/hash_map_key_iterator.rs | 10 +- .../src/classes/java/util/hash_map_key_set.rs | 34 ++++-- .../java/util/hash_map_value_iterator.rs | 10 +- .../src/classes/java/util/hash_map_values.rs | 28 +++-- .../src/classes/java/util/hash_set.rs | 26 ++--- .../src/classes/java/util/hashtable.rs | 14 ++- .../src/classes/java/util/hashtable_entry.rs | 25 +++-- .../classes/java/util/hashtable_entry_set.rs | 18 +-- .../classes/java/util/hashtable_enumerator.rs | 19 ++-- .../classes/java/util/hashtable_key_set.rs | 19 ++-- .../src/classes/java/util/hashtable_values.rs | 18 +-- .../java/util/illegal_format_exception.rs | 4 +- .../src/classes/java/util/jar/attributes.rs | 16 ++- .../src/classes/java/util/jar/jar_entry.rs | 5 +- .../classes/java/util/jar/jar_file_entries.rs | 15 ++- .../src/classes/java/util/jar/manifest.rs | 4 +- .../src/classes/java/util/linked_hash_map.rs | 22 +++- .../java/util/linked_hash_map_entry.rs | 13 ++- .../util/linked_hash_map_entry_iterator.rs | 6 +- .../java/util/linked_hash_map_key_iterator.rs | 6 +- .../linked_hash_map_linked_hash_iterator.rs | 19 ++-- .../util/linked_hash_map_value_iterator.rs | 6 +- .../classes/java/util/linked_list_entry.rs | 11 +- .../src/classes/java/util/linked_list_itr.rs | 12 +- java_runtime/src/classes/java/util/locale.rs | 55 +++++---- .../java/util/no_such_element_exception.rs | 7 +- .../src/classes/java/util/timer_task.rs | 8 +- .../src/classes/java/util/timer_task_queue.rs | 6 +- .../src/classes/java/util/timer_thread.rs | 8 +- .../src/classes/java/util/tree_map.rs | 16 ++- .../src/classes/java/util/tree_map_entry.rs | 2 +- .../java/util/tree_map_entry_iterator.rs | 6 +- .../classes/java/util/tree_map_entry_set.rs | 6 +- .../java/util/tree_map_key_iterator.rs | 6 +- .../src/classes/java/util/tree_map_key_set.rs | 6 +- .../util/tree_map_private_entry_iterator.rs | 2 +- .../src/classes/java/util/tree_map_sub_map.rs | 22 +++- .../java/util/tree_map_value_iterator.rs | 6 +- .../src/classes/java/util/tree_map_values.rs | 6 +- .../src/classes/java/util/tree_set.rs | 2 +- .../src/classes/java/util/vector_itr.rs | 16 +-- .../src/classes/java/util/zip/zip_entry.rs | 22 ++-- .../classes/java/util/zip/zip_exception.rs | 7 +- .../src/classes/java/util/zip/zip_file.rs | 4 +- .../classes/java/util/zip/zip_file_entries.rs | 20 ++-- .../rustjava/lang/rust_jar_class_loader.rs | 6 +- .../org/rustjava/net/file_url_connection.rs | 8 +- .../org/rustjava/net/file_url_handler.rs | 6 +- .../org/rustjava/net/jar_url_connection.rs | 6 +- .../org/rustjava/net/jar_url_handler.rs | 6 +- .../classes/java/io/test_buffered_reader.rs | 39 +++---- .../java/io/test_input_stream_reader.rs | 13 ++- .../classes/java/io/test_print_writer.rs | 70 ++++++------ .../classes/java/io/test_stream_locking.rs | 37 +++--- .../tests/classes/java/lang/test_class.rs | 14 ++- .../tests/classes/java/lang/test_object.rs | 7 +- .../tests/classes/java/lang/test_thread.rs | 10 +- .../tests/classes/java/util/test_arrays.rs | 24 ++-- .../java/util/test_collection_contracts.rs | 28 ++--- .../classes/java/util/test_collections.rs | 62 +++++----- .../tests/classes/java/util/test_hash_map.rs | 46 ++++---- .../classes/java/util/test_linked_hash_map.rs | 6 +- .../tests/classes/java/util/test_tree_map.rs | 30 ++--- 161 files changed, 1320 insertions(+), 908 deletions(-) diff --git a/java_runtime/src/classes/java/io/byte_array_input_stream.rs b/java_runtime/src/classes/java/io/byte_array_input_stream.rs index 5d1894e8..eafe9094 100644 --- a/java_runtime/src/classes/java/io/byte_array_input_stream.rs +++ b/java_runtime/src/classes/java/io/byte_array_input_stream.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext}; @@ -15,24 +16,34 @@ impl ByteArrayInputStream { parent_class: Some("java/io/InputStream"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "([B)V", Self::init, Default::default()), - JavaMethodProto::new("", "([BII)V", Self::init_with_offset_length, Default::default()), - JavaMethodProto::new("available", "()I", Self::available, Default::default()), - JavaMethodProto::new("read", "([BII)I", Self::read, Default::default()), - JavaMethodProto::new("read", "()I", Self::read_byte, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), - JavaMethodProto::new("skip", "(J)J", Self::skip, Default::default()), - JavaMethodProto::new("mark", "(I)V", Self::mark, Default::default()), - JavaMethodProto::new("reset", "()V", Self::reset, Default::default()), - JavaMethodProto::new("markSupported", "()Z", Self::mark_supported, Default::default()), + JavaMethodProto::new("", "([B)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "([BII)V", Self::init_with_offset_length, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "available", + "()I", + Self::available, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new("read", "([BII)I", Self::read, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED), + JavaMethodProto::new( + "read", + "()I", + Self::read_byte, + MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED, + ), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("skip", "(J)J", Self::skip, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED), + JavaMethodProto::new("mark", "(I)V", Self::mark, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("reset", "()V", Self::reset, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED), + JavaMethodProto::new("markSupported", "()Z", Self::mark_supported, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("buf", "[B", Default::default()), - JavaFieldProto::new("pos", "I", Default::default()), - JavaFieldProto::new("count", "I", Default::default()), - JavaFieldProto::new("mark", "I", Default::default()), + JavaFieldProto::new("buf", "[B", FieldAccessFlags::PROTECTED), + JavaFieldProto::new("pos", "I", FieldAccessFlags::PROTECTED), + JavaFieldProto::new("count", "I", FieldAccessFlags::PROTECTED), + JavaFieldProto::new("mark", "I", FieldAccessFlags::PROTECTED), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/data_input.rs b/java_runtime/src/classes/java/io/data_input.rs index cfc65def..e4322bf6 100644 --- a/java_runtime/src/classes/java/io/data_input.rs +++ b/java_runtime/src/classes/java/io/data_input.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use crate::RuntimeClassProto; // interface java.io.DataInput @@ -14,20 +14,20 @@ impl DataInput { parent_class: None, interfaces: vec![], methods: vec![ - JavaMethodProto::new_abstract("readBoolean", "()Z", Default::default()), - JavaMethodProto::new_abstract("readByte", "()B", Default::default()), - JavaMethodProto::new_abstract("readChar", "()C", Default::default()), - JavaMethodProto::new_abstract("readDouble", "()D", Default::default()), - JavaMethodProto::new_abstract("readFloat", "()F", Default::default()), - JavaMethodProto::new_abstract("readFully", "([B)V", Default::default()), - JavaMethodProto::new_abstract("readFully", "([BII)V", Default::default()), - JavaMethodProto::new_abstract("readInt", "()I", Default::default()), - JavaMethodProto::new_abstract("readLong", "()J", Default::default()), - JavaMethodProto::new_abstract("readShort", "()S", Default::default()), - JavaMethodProto::new_abstract("readUnsignedByte", "()I", Default::default()), - JavaMethodProto::new_abstract("readUnsignedShort", "()I", Default::default()), - JavaMethodProto::new_abstract("readUTF", "()Ljava/lang/String;", Default::default()), - JavaMethodProto::new_abstract("skipBytes", "(I)I", Default::default()), + JavaMethodProto::new_abstract("readBoolean", "()Z", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readByte", "()B", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readChar", "()C", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readDouble", "()D", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readFloat", "()F", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readFully", "([B)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readFully", "([BII)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readInt", "()I", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readLong", "()J", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readShort", "()S", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readUnsignedByte", "()I", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readUnsignedShort", "()I", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("readUTF", "()Ljava/lang/String;", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("skipBytes", "(I)I", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), ], fields: vec![], access_flags: ClassAccessFlags::INTERFACE, diff --git a/java_runtime/src/classes/java/io/data_input_stream.rs b/java_runtime/src/classes/java/io/data_input_stream.rs index 20cc5c0d..30f10d6c 100644 --- a/java_runtime/src/classes/java/io/data_input_stream.rs +++ b/java_runtime/src/classes/java/io/data_input_stream.rs @@ -1,7 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaChar, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -22,30 +22,70 @@ impl DataInputStream { parent_class: Some("java/io/FilterInputStream"), interfaces: vec!["java/io/DataInput"], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/InputStream;)V", Self::init, Default::default()), - JavaMethodProto::new("readBoolean", "()Z", Self::read_boolean, Default::default()), - JavaMethodProto::new("readByte", "()B", Self::read_byte, Default::default()), - JavaMethodProto::new("readChar", "()C", Self::read_char, Default::default()), - JavaMethodProto::new("readDouble", "()D", Self::read_double, Default::default()), - JavaMethodProto::new("readFloat", "()F", Self::read_float, Default::default()), - JavaMethodProto::new("readFully", "([B)V", Self::read_fully, Default::default()), - JavaMethodProto::new("readFully", "([BII)V", Self::read_fully_offset_length, Default::default()), - JavaMethodProto::new("readInt", "()I", Self::read_int, Default::default()), - JavaMethodProto::new("readLong", "()J", Self::read_long, Default::default()), - JavaMethodProto::new("readShort", "()S", Self::read_short, Default::default()), - JavaMethodProto::new("readUnsignedByte", "()I", Self::read_unsigned_byte, Default::default()), - JavaMethodProto::new("readUnsignedShort", "()I", Self::read_unsigned_short, Default::default()), - JavaMethodProto::new("readUTF", "()Ljava/lang/String;", Self::read_utf, Default::default()), + JavaMethodProto::new("", "(Ljava/io/InputStream;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "readBoolean", + "()Z", + Self::read_boolean, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new("readByte", "()B", Self::read_byte, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("readChar", "()C", Self::read_char, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new( + "readDouble", + "()D", + Self::read_double, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new("readFloat", "()F", Self::read_float, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new( + "readFully", + "([B)V", + Self::read_fully, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "readFully", + "([BII)V", + Self::read_fully_offset_length, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new("readInt", "()I", Self::read_int, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("readLong", "()J", Self::read_long, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("readShort", "()S", Self::read_short, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new( + "readUnsignedByte", + "()I", + Self::read_unsigned_byte, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "readUnsignedShort", + "()I", + Self::read_unsigned_short, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "readUTF", + "()Ljava/lang/String;", + Self::read_utf, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), JavaMethodProto::new( "readUTF", "(Ljava/io/DataInput;)Ljava/lang/String;", Self::read_utf_from_input, MethodAccessFlags::STATIC, ), - JavaMethodProto::new("skipBytes", "(I)I", Self::skip_bytes, Default::default()), + JavaMethodProto::new( + "skipBytes", + "(I)I", + Self::skip_bytes, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/data_output.rs b/java_runtime/src/classes/java/io/data_output.rs index 6021851b..89b3cd5a 100644 --- a/java_runtime/src/classes/java/io/data_output.rs +++ b/java_runtime/src/classes/java/io/data_output.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use crate::RuntimeClassProto; @@ -15,20 +15,32 @@ impl DataOutput { parent_class: None, interfaces: vec![], methods: vec![ - JavaMethodProto::new_abstract("write", "(I)V", Default::default()), - JavaMethodProto::new_abstract("write", "([B)V", Default::default()), - JavaMethodProto::new_abstract("write", "([BII)V", Default::default()), - JavaMethodProto::new_abstract("writeByte", "(I)V", Default::default()), - JavaMethodProto::new_abstract("writeBoolean", "(Z)V", Default::default()), - JavaMethodProto::new_abstract("writeInt", "(I)V", Default::default()), - JavaMethodProto::new_abstract("writeShort", "(I)V", Default::default()), - JavaMethodProto::new_abstract("writeChar", "(I)V", Default::default()), - JavaMethodProto::new_abstract("writeLong", "(J)V", Default::default()), - JavaMethodProto::new_abstract("writeFloat", "(F)V", Default::default()), - JavaMethodProto::new_abstract("writeDouble", "(D)V", Default::default()), - JavaMethodProto::new_abstract("writeBytes", "(Ljava/lang/String;)V", Default::default()), - JavaMethodProto::new_abstract("writeChars", "(Ljava/lang/String;)V", Default::default()), - JavaMethodProto::new_abstract("writeUTF", "(Ljava/lang/String;)V", Default::default()), + JavaMethodProto::new_abstract("write", "(I)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("write", "([B)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("write", "([BII)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("writeByte", "(I)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("writeBoolean", "(Z)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("writeInt", "(I)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("writeShort", "(I)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("writeChar", "(I)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("writeLong", "(J)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("writeFloat", "(F)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract("writeDouble", "(D)V", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract( + "writeBytes", + "(Ljava/lang/String;)V", + MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT, + ), + JavaMethodProto::new_abstract( + "writeChars", + "(Ljava/lang/String;)V", + MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT, + ), + JavaMethodProto::new_abstract( + "writeUTF", + "(Ljava/lang/String;)V", + MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT, + ), ], fields: vec![], access_flags: ClassAccessFlags::INTERFACE, diff --git a/java_runtime/src/classes/java/io/data_output_stream.rs b/java_runtime/src/classes/java/io/data_output_stream.rs index 7bf2a652..4680878b 100644 --- a/java_runtime/src/classes/java/io/data_output_stream.rs +++ b/java_runtime/src/classes/java/io/data_output_stream.rs @@ -3,6 +3,7 @@ use alloc::{vec, vec::Vec}; use bytemuck::cast_vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaChar, Jvm, Result}; use crate::{ @@ -20,24 +21,74 @@ impl DataOutputStream { parent_class: Some("java/io/FilterOutputStream"), interfaces: vec!["java/io/DataOutput"], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/OutputStream;)V", Self::init, Default::default()), - JavaMethodProto::new("write", "(I)V", Self::write, Default::default()), - JavaMethodProto::new("writeByte", "(I)V", Self::write_byte, Default::default()), - JavaMethodProto::new("writeBoolean", "(Z)V", Self::write_boolean, Default::default()), - JavaMethodProto::new("writeInt", "(I)V", Self::write_int, Default::default()), - JavaMethodProto::new("writeShort", "(I)V", Self::write_short, Default::default()), - JavaMethodProto::new("writeChar", "(I)V", Self::write_char, Default::default()), - JavaMethodProto::new("writeLong", "(J)V", Self::write_long, Default::default()), - JavaMethodProto::new("writeFloat", "(F)V", Self::write_float, Default::default()), - JavaMethodProto::new("writeDouble", "(D)V", Self::write_double, Default::default()), - JavaMethodProto::new("writeBytes", "(Ljava/lang/String;)V", Self::write_bytes, Default::default()), - JavaMethodProto::new("writeChars", "(Ljava/lang/String;)V", Self::write_chars, Default::default()), - JavaMethodProto::new("writeUTF", "(Ljava/lang/String;)V", Self::write_utf, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), - JavaMethodProto::new("flush", "()V", Self::flush, Default::default()), + JavaMethodProto::new("", "(Ljava/io/OutputStream;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("write", "(I)V", Self::write, MethodAccessFlags::PUBLIC | MethodAccessFlags::SYNCHRONIZED), + JavaMethodProto::new( + "writeByte", + "(I)V", + Self::write_byte, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "writeBoolean", + "(Z)V", + Self::write_boolean, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new("writeInt", "(I)V", Self::write_int, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new( + "writeShort", + "(I)V", + Self::write_short, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "writeChar", + "(I)V", + Self::write_char, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "writeLong", + "(J)V", + Self::write_long, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "writeFloat", + "(F)V", + Self::write_float, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "writeDouble", + "(D)V", + Self::write_double, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "writeBytes", + "(Ljava/lang/String;)V", + Self::write_bytes, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "writeChars", + "(Ljava/lang/String;)V", + Self::write_chars, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "writeUTF", + "(Ljava/lang/String;)V", + Self::write_utf, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("flush", "()V", Self::flush, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/eof_exception.rs b/java_runtime/src/classes/java/io/eof_exception.rs index 0e8f7b47..525b4d4f 100644 --- a/java_runtime/src/classes/java/io/eof_exception.rs +++ b/java_runtime/src/classes/java/io/eof_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl EOFException { parent_class: Some("java/io/IOException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/file.rs b/java_runtime/src/classes/java/io/file.rs index 641f5bf7..99297324 100644 --- a/java_runtime/src/classes/java/io/file.rs +++ b/java_runtime/src/classes/java/io/file.rs @@ -46,7 +46,7 @@ impl File { "Ljava/lang/String;", FieldAccessFlags::PUBLIC | FieldAccessFlags::STATIC | FieldAccessFlags::FINAL, ), - JavaFieldProto::new("path", "Ljava/lang/String;", Default::default()), + JavaFieldProto::new("path", "Ljava/lang/String;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL), ], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/src/classes/java/io/file_descriptor.rs b/java_runtime/src/classes/java/io/file_descriptor.rs index 0907d567..5b084eb5 100644 --- a/java_runtime/src/classes/java/io/file_descriptor.rs +++ b/java_runtime/src/classes/java/io/file_descriptor.rs @@ -1,7 +1,7 @@ use alloc::{boxed::Box, vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext}; @@ -16,16 +16,16 @@ impl FileDescriptor { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new("", "()V", Self::cl_init, MethodAccessFlags::STATIC), ], fields: vec![ - JavaFieldProto::new("fd", "I", Default::default()), + JavaFieldProto::new("fd", "I", FieldAccessFlags::PRIVATE), JavaFieldProto::new("err", "Ljava/io/FileDescriptor;", FieldAccessFlags::STATIC), JavaFieldProto::new("in", "Ljava/io/FileDescriptor;", FieldAccessFlags::STATIC), JavaFieldProto::new("out", "Ljava/io/FileDescriptor;", FieldAccessFlags::STATIC), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/io/file_input_stream.rs b/java_runtime/src/classes/java/io/file_input_stream.rs index b75e3ea9..c229772d 100644 --- a/java_runtime/src/classes/java/io/file_input_stream.rs +++ b/java_runtime/src/classes/java/io/file_input_stream.rs @@ -3,6 +3,7 @@ use alloc::vec; use bytemuck::cast_vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -20,20 +21,24 @@ impl FileInputStream { parent_class: Some("java/io/InputStream"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/File;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/io/File;)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/io/FileDescriptor;)V", Self::init_with_file_descriptor, - Default::default(), + MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("read", "()I", Self::read_byte, Default::default()), - JavaMethodProto::new("read", "([BII)I", Self::read_array, Default::default()), - JavaMethodProto::new("available", "()I", Self::available, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), + JavaMethodProto::new("read", "()I", Self::read_byte, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "([BII)I", Self::read_array, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("available", "()I", Self::available, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("fd", "Ljava/io/FileDescriptor;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new( + "fd", + "Ljava/io/FileDescriptor;", + FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, + )], + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/file_not_found_exception.rs b/java_runtime/src/classes/java/io/file_not_found_exception.rs index ac71618d..4ca66331 100644 --- a/java_runtime/src/classes/java/io/file_not_found_exception.rs +++ b/java_runtime/src/classes/java/io/file_not_found_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl FileNotFoundException { parent_class: Some("java/io/IOException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/file_output_stream.rs b/java_runtime/src/classes/java/io/file_output_stream.rs index 61bf7dc0..3e53e79a 100644 --- a/java_runtime/src/classes/java/io/file_output_stream.rs +++ b/java_runtime/src/classes/java/io/file_output_stream.rs @@ -3,7 +3,7 @@ use alloc::vec; use bytemuck::cast_slice; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -21,23 +21,23 @@ impl FileOutputStream { parent_class: Some("java/io/OutputStream"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/File;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/io/File;)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new("", "(Ljava/io/File;Z)V", Self::init_with_append, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/io/FileDescriptor;)V", Self::init_with_file_descriptor, - Default::default(), + MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("write", "([BII)V", Self::write_bytes_offset, Default::default()), - JavaMethodProto::new("write", "(I)V", Self::write, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), + JavaMethodProto::new("write", "([BII)V", Self::write_bytes_offset, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("write", "(I)V", Self::write, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("fd", "Ljava/io/FileDescriptor;", Default::default()), + JavaFieldProto::new("fd", "Ljava/io/FileDescriptor;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL), JavaFieldProto::new("append", "Z", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/input_stream_reader.rs b/java_runtime/src/classes/java/io/input_stream_reader.rs index d1645fd3..79c0d1eb 100644 --- a/java_runtime/src/classes/java/io/input_stream_reader.rs +++ b/java_runtime/src/classes/java/io/input_stream_reader.rs @@ -6,6 +6,7 @@ use bytemuck::{cast_slice, cast_vec}; use encoding_rs::{EUC_KR, UTF_8}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaChar, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -25,27 +26,27 @@ impl InputStreamReader { parent_class: Some("java/io/Reader"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/InputStream;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/io/InputStream;)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/io/InputStream;Ljava/lang/String;)V", Self::init_with_charset, - Default::default(), + MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("read", "([CII)I", Self::read, Default::default()), - JavaMethodProto::new("ready", "()Z", Self::ready, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), + JavaMethodProto::new("read", "([CII)I", Self::read, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("ready", "()Z", Self::ready, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("in", "Ljava/io/InputStream;", Default::default()), - JavaFieldProto::new("readBuf", "[B", Default::default()), - JavaFieldProto::new("readBufSize", "I", Default::default()), - JavaFieldProto::new("writeBuf", "[C", Default::default()), - JavaFieldProto::new("writeBufSize", "I", Default::default()), - JavaFieldProto::new("charset", "Ljava/lang/String;", Default::default()), - JavaFieldProto::new("endOfInput", "Z", Default::default()), + JavaFieldProto::new("in", "Ljava/io/InputStream;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("readBuf", "[B", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("readBufSize", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("writeBuf", "[C", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("writeBufSize", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("charset", "Ljava/lang/String;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("endOfInput", "Z", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/interrupted_io_exception.rs b/java_runtime/src/classes/java/io/interrupted_io_exception.rs index 1ddbe07b..aa40f50b 100644 --- a/java_runtime/src/classes/java/io/interrupted_io_exception.rs +++ b/java_runtime/src/classes/java/io/interrupted_io_exception.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::FieldAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -16,11 +16,11 @@ impl InterruptedIOException { parent_class: Some("java/io/IOException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("bytesTransferred", "I", FieldAccessFlags::PUBLIC)], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/io_exception.rs b/java_runtime/src/classes/java/io/io_exception.rs index 2ec2ecc4..f9cab76f 100644 --- a/java_runtime/src/classes/java/io/io_exception.rs +++ b/java_runtime/src/classes/java/io/io_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl IOException { parent_class: Some("java/lang/Exception"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/output_stream_writer.rs b/java_runtime/src/classes/java/io/output_stream_writer.rs index b0c857ac..b56905a1 100644 --- a/java_runtime/src/classes/java/io/output_stream_writer.rs +++ b/java_runtime/src/classes/java/io/output_stream_writer.rs @@ -1,7 +1,7 @@ use alloc::{string::String as RustString, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaChar, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -34,10 +34,10 @@ impl OutputStreamWriter { JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("out", "Ljava/io/OutputStream;", Default::default()), - JavaFieldProto::new("encoding", "Ljava/lang/String;", Default::default()), - JavaFieldProto::new("pendingHighSurrogate", "C", Default::default()), - JavaFieldProto::new("hasPendingHighSurrogate", "Z", Default::default()), + JavaFieldProto::new("out", "Ljava/io/OutputStream;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("encoding", "Ljava/lang/String;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("pendingHighSurrogate", "C", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("hasPendingHighSurrogate", "Z", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/src/classes/java/io/random_access_file.rs b/java_runtime/src/classes/java/io/random_access_file.rs index 68fc1a08..e1f02019 100644 --- a/java_runtime/src/classes/java/io/random_access_file.rs +++ b/java_runtime/src/classes/java/io/random_access_file.rs @@ -3,7 +3,7 @@ use alloc::vec; use bytemuck::cast_vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -47,7 +47,11 @@ impl RandomAccessFile { JavaMethodProto::new("setLength", "(J)V", Self::set_length, MethodAccessFlags::PUBLIC), JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("fd", "Ljava/io/FileDescriptor;", Default::default())], + fields: vec![JavaFieldProto::new( + "fd", + "Ljava/io/FileDescriptor;", + FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, + )], access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/string_writer.rs b/java_runtime/src/classes/java/io/string_writer.rs index fc82ba33..a57b54ce 100644 --- a/java_runtime/src/classes/java/io/string_writer.rs +++ b/java_runtime/src/classes/java/io/string_writer.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaChar, Jvm, Result}; use crate::{ @@ -25,7 +25,11 @@ impl StringWriter { JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("buf", "Ljava/lang/StringBuffer;", Default::default())], + fields: vec![JavaFieldProto::new( + "buf", + "Ljava/lang/StringBuffer;", + FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, + )], access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/unsupported_encoding_exception.rs b/java_runtime/src/classes/java/io/unsupported_encoding_exception.rs index 72cc7cea..0b5ed007 100644 --- a/java_runtime/src/classes/java/io/unsupported_encoding_exception.rs +++ b/java_runtime/src/classes/java/io/unsupported_encoding_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl UnsupportedEncodingException { parent_class: Some("java/io/IOException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/io/utf_data_format_exception.rs b/java_runtime/src/classes/java/io/utf_data_format_exception.rs index 35e664f2..e1579f96 100644 --- a/java_runtime/src/classes/java/io/utf_data_format_exception.rs +++ b/java_runtime/src/classes/java/io/utf_data_format_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl UTFDataFormatException { parent_class: Some("java/io/IOException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/abstract_method_error.rs b/java_runtime/src/classes/java/lang/abstract_method_error.rs index 244637f5..0a18a441 100644 --- a/java_runtime/src/classes/java/lang/abstract_method_error.rs +++ b/java_runtime/src/classes/java/lang/abstract_method_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl AbstractMethodError { parent_class: Some("java/lang/IncompatibleClassChangeError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/abstract_string_builder.rs b/java_runtime/src/classes/java/lang/abstract_string_builder.rs index 88cee38a..e02f15d4 100644 --- a/java_runtime/src/classes/java/lang/abstract_string_builder.rs +++ b/java_runtime/src/classes/java/lang/abstract_string_builder.rs @@ -1,7 +1,7 @@ use alloc::{format, string::ToString, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaChar, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -19,8 +19,8 @@ impl AbstractStringBuilder { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Appendable", "java/lang/CharSequence"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(I)V", Self::init_with_capacity, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::empty()), + JavaMethodProto::new("", "(I)V", Self::init_with_capacity, MethodAccessFlags::empty()), JavaMethodProto::new("length", "()I", Self::length, MethodAccessFlags::PUBLIC), JavaMethodProto::new("capacity", "()I", Self::capacity, MethodAccessFlags::PUBLIC), JavaMethodProto::new("ensureCapacity", "(I)V", Self::ensure_capacity, MethodAccessFlags::PUBLIC), @@ -240,8 +240,8 @@ impl AbstractStringBuilder { ), ], fields: vec![ - JavaFieldProto::new("value", "[C", Default::default()), - JavaFieldProto::new("count", "I", Default::default()), + JavaFieldProto::new("value", "[C", FieldAccessFlags::empty()), + JavaFieldProto::new("count", "I", FieldAccessFlags::empty()), ], access_flags: ClassAccessFlags::ABSTRACT, } diff --git a/java_runtime/src/classes/java/lang/arithmetic_exception.rs b/java_runtime/src/classes/java/lang/arithmetic_exception.rs index 35177d0a..cee62369 100644 --- a/java_runtime/src/classes/java/lang/arithmetic_exception.rs +++ b/java_runtime/src/classes/java/lang/arithmetic_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl ArithmeticException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/array_index_out_of_bounds_exception.rs b/java_runtime/src/classes/java/lang/array_index_out_of_bounds_exception.rs index adbf333d..abc86c46 100644 --- a/java_runtime/src/classes/java/lang/array_index_out_of_bounds_exception.rs +++ b/java_runtime/src/classes/java/lang/array_index_out_of_bounds_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl ArrayIndexOutOfBoundsException { parent_class: Some("java/lang/IndexOutOfBoundsException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/array_store_exception.rs b/java_runtime/src/classes/java/lang/array_store_exception.rs index d715e8a4..50291624 100644 --- a/java_runtime/src/classes/java/lang/array_store_exception.rs +++ b/java_runtime/src/classes/java/lang/array_store_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl ArrayStoreException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/class.rs b/java_runtime/src/classes/java/lang/class.rs index 1097757e..31f149e6 100644 --- a/java_runtime/src/classes/java/lang/class.rs +++ b/java_runtime/src/classes/java/lang/class.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ ClassInstanceRef, JavaType, Jvm, Result, runtime::{JavaLangClass, JavaLangClassLoader, JavaLangString}, @@ -25,13 +25,18 @@ impl Class { parent_class: Some("java/lang/Object"), interfaces: vec!["java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("getName", "()Ljava/lang/String;", Self::get_name, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PRIVATE), + JavaMethodProto::new("getName", "()Ljava/lang/String;", Self::get_name, MethodAccessFlags::PUBLIC), JavaMethodProto::new("isPrimitive", "()Z", Self::is_primitive, MethodAccessFlags::PUBLIC), JavaMethodProto::new("isArray", "()Z", Self::is_array, MethodAccessFlags::PUBLIC), JavaMethodProto::new("isInterface", "()Z", Self::is_interface, MethodAccessFlags::PUBLIC), JavaMethodProto::new("isInstance", "(Ljava/lang/Object;)Z", Self::is_instance, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("isAssignableFrom", "(Ljava/lang/Class;)Z", Self::is_assignable_from, Default::default()), + JavaMethodProto::new( + "isAssignableFrom", + "(Ljava/lang/Class;)Z", + Self::is_assignable_from, + MethodAccessFlags::PUBLIC | MethodAccessFlags::NATIVE, + ), JavaMethodProto::new("newInstance", "()Ljava/lang/Object;", Self::new_instance, MethodAccessFlags::PUBLIC), JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, MethodAccessFlags::PUBLIC), JavaMethodProto::new("getSuperclass", "()Ljava/lang/Class;", Self::get_superclass, MethodAccessFlags::PUBLIC), @@ -52,7 +57,7 @@ impl Class { "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;", Self::get_resource_as_stream, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "forName", @@ -64,10 +69,14 @@ impl Class { fields: vec![ // Stored as raw bytes instead of java/lang/String to avoid circular dependency: // from_rust_class -> JavaLangString::from_rust_string -> new_class("java/lang/String") -> from_rust_class -> stack overflow - JavaFieldProto::new("nameBytes", "[B", Default::default()), - JavaFieldProto::new("classLoader", "Ljava/lang/ClassLoader;", Default::default()), + JavaFieldProto::new("nameBytes", "[B", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL), + JavaFieldProto::new( + "classLoader", + "Ljava/lang/ClassLoader;", + FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, + ), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/lang/class_cast_exception.rs b/java_runtime/src/classes/java/lang/class_cast_exception.rs index 37bd8aba..d64b3e2f 100644 --- a/java_runtime/src/classes/java/lang/class_cast_exception.rs +++ b/java_runtime/src/classes/java/lang/class_cast_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl ClassCastException { parent_class: Some("java/lang/Exception"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/class_format_error.rs b/java_runtime/src/classes/java/lang/class_format_error.rs index 0dbd369a..afc805de 100644 --- a/java_runtime/src/classes/java/lang/class_format_error.rs +++ b/java_runtime/src/classes/java/lang/class_format_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl ClassFormatError { parent_class: Some("java/lang/LinkageError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/class_loader.rs b/java_runtime/src/classes/java/lang/class_loader.rs index 0345b6bd..616b4d44 100644 --- a/java_runtime/src/classes/java/lang/class_loader.rs +++ b/java_runtime/src/classes/java/lang/class_loader.rs @@ -1,7 +1,7 @@ use alloc::{format, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -74,9 +74,9 @@ impl ClassLoader { ], fields: vec![ JavaFieldProto::new("systemClassLoader", "Ljava/lang/ClassLoader;", FieldAccessFlags::STATIC), - JavaFieldProto::new("parent", "Ljava/lang/ClassLoader;", Default::default()), + JavaFieldProto::new("parent", "Ljava/lang/ClassLoader;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::ABSTRACT, } } diff --git a/java_runtime/src/classes/java/lang/class_not_found_exception.rs b/java_runtime/src/classes/java/lang/class_not_found_exception.rs index f4f48d30..9dbae2e9 100644 --- a/java_runtime/src/classes/java/lang/class_not_found_exception.rs +++ b/java_runtime/src/classes/java/lang/class_not_found_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl ClassNotFoundException { parent_class: Some("java/lang/Exception"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/clone_not_supported_exception.rs b/java_runtime/src/classes/java/lang/clone_not_supported_exception.rs index efc707c8..de255202 100644 --- a/java_runtime/src/classes/java/lang/clone_not_supported_exception.rs +++ b/java_runtime/src/classes/java/lang/clone_not_supported_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl CloneNotSupportedException { parent_class: Some("java/lang/Exception"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/error.rs b/java_runtime/src/classes/java/lang/error.rs index 545c315a..4a44f10d 100644 --- a/java_runtime/src/classes/java/lang/error.rs +++ b/java_runtime/src/classes/java/lang/error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl Error { parent_class: Some("java/lang/Throwable"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/exception.rs b/java_runtime/src/classes/java/lang/exception.rs index b48609e8..1e4096a8 100644 --- a/java_runtime/src/classes/java/lang/exception.rs +++ b/java_runtime/src/classes/java/lang/exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -18,18 +19,18 @@ impl Exception { parent_class: Some("java/lang/Throwable"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/Throwable;)V", Self::init_with_cause, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/Throwable;)V", Self::init_with_cause, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/lang/String;Ljava/lang/Throwable;)V", Self::init_with_message_and_cause, - Default::default(), + MethodAccessFlags::PUBLIC, ), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/exception_in_initializer_error.rs b/java_runtime/src/classes/java/lang/exception_in_initializer_error.rs index 9d0c9c7f..df76daf5 100644 --- a/java_runtime/src/classes/java/lang/exception_in_initializer_error.rs +++ b/java_runtime/src/classes/java/lang/exception_in_initializer_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -18,13 +19,13 @@ impl ExceptionInInitializerError { parent_class: Some("java/lang/LinkageError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/Throwable;)V", Self::init_with_cause, Default::default()), - JavaMethodProto::new("getException", "()Ljava/lang/Throwable;", Self::get_exception, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/Throwable;)V", Self::init_with_cause, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getException", "()Ljava/lang/Throwable;", Self::get_exception, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/illegal_access_exception.rs b/java_runtime/src/classes/java/lang/illegal_access_exception.rs index 92fa58aa..723b0d68 100644 --- a/java_runtime/src/classes/java/lang/illegal_access_exception.rs +++ b/java_runtime/src/classes/java/lang/illegal_access_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl IllegalAccessException { parent_class: Some("java/lang/Exception"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/illegal_argument_exception.rs b/java_runtime/src/classes/java/lang/illegal_argument_exception.rs index 5501c6c5..3f6ba283 100644 --- a/java_runtime/src/classes/java/lang/illegal_argument_exception.rs +++ b/java_runtime/src/classes/java/lang/illegal_argument_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl IllegalArgumentException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/illegal_monitor_state_exception.rs b/java_runtime/src/classes/java/lang/illegal_monitor_state_exception.rs index 4eb45b11..3e57a56b 100644 --- a/java_runtime/src/classes/java/lang/illegal_monitor_state_exception.rs +++ b/java_runtime/src/classes/java/lang/illegal_monitor_state_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl IllegalMonitorStateException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/illegal_thread_state_exception.rs b/java_runtime/src/classes/java/lang/illegal_thread_state_exception.rs index eb419220..b18815b6 100644 --- a/java_runtime/src/classes/java/lang/illegal_thread_state_exception.rs +++ b/java_runtime/src/classes/java/lang/illegal_thread_state_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl IllegalThreadStateException { parent_class: Some("java/lang/IllegalArgumentException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/incompatible_class_change_error.rs b/java_runtime/src/classes/java/lang/incompatible_class_change_error.rs index 946aa7e1..10408df0 100644 --- a/java_runtime/src/classes/java/lang/incompatible_class_change_error.rs +++ b/java_runtime/src/classes/java/lang/incompatible_class_change_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl IncompatibleClassChangeError { parent_class: Some("java/lang/LinkageError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/index_out_of_bounds_exception.rs b/java_runtime/src/classes/java/lang/index_out_of_bounds_exception.rs index c33e7c31..58033f93 100644 --- a/java_runtime/src/classes/java/lang/index_out_of_bounds_exception.rs +++ b/java_runtime/src/classes/java/lang/index_out_of_bounds_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl IndexOutOfBoundsException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/instantiation_error.rs b/java_runtime/src/classes/java/lang/instantiation_error.rs index 6de62a7c..5309ea87 100644 --- a/java_runtime/src/classes/java/lang/instantiation_error.rs +++ b/java_runtime/src/classes/java/lang/instantiation_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl InstantiationError { parent_class: Some("java/lang/IncompatibleClassChangeError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/instantiation_exception.rs b/java_runtime/src/classes/java/lang/instantiation_exception.rs index aa25d858..be5475cc 100644 --- a/java_runtime/src/classes/java/lang/instantiation_exception.rs +++ b/java_runtime/src/classes/java/lang/instantiation_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl InstantiationException { parent_class: Some("java/lang/Exception"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/interrupted_exception.rs b/java_runtime/src/classes/java/lang/interrupted_exception.rs index c2e7fef7..727150e7 100644 --- a/java_runtime/src/classes/java/lang/interrupted_exception.rs +++ b/java_runtime/src/classes/java/lang/interrupted_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl InterruptedException { parent_class: Some("java/lang/Exception"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/linkage_error.rs b/java_runtime/src/classes/java/lang/linkage_error.rs index 56801942..3ff045df 100644 --- a/java_runtime/src/classes/java/lang/linkage_error.rs +++ b/java_runtime/src/classes/java/lang/linkage_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl LinkageError { parent_class: Some("java/lang/Error"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/negative_array_size_exception.rs b/java_runtime/src/classes/java/lang/negative_array_size_exception.rs index 3b9d50bd..e0a03781 100644 --- a/java_runtime/src/classes/java/lang/negative_array_size_exception.rs +++ b/java_runtime/src/classes/java/lang/negative_array_size_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -14,11 +15,11 @@ impl NegativeArraySizeException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/no_class_def_found_error.rs b/java_runtime/src/classes/java/lang/no_class_def_found_error.rs index 7a93a369..6268c486 100644 --- a/java_runtime/src/classes/java/lang/no_class_def_found_error.rs +++ b/java_runtime/src/classes/java/lang/no_class_def_found_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl NoClassDefFoundError { parent_class: Some("java/lang/LinkageError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/no_such_field_error.rs b/java_runtime/src/classes/java/lang/no_such_field_error.rs index 9707b4fe..a6ea28f5 100644 --- a/java_runtime/src/classes/java/lang/no_such_field_error.rs +++ b/java_runtime/src/classes/java/lang/no_such_field_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl NoSuchFieldError { parent_class: Some("java/lang/IncompatibleClassChangeError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/no_such_method_error.rs b/java_runtime/src/classes/java/lang/no_such_method_error.rs index 36099f8e..ec51b1cb 100644 --- a/java_runtime/src/classes/java/lang/no_such_method_error.rs +++ b/java_runtime/src/classes/java/lang/no_such_method_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl NoSuchMethodError { parent_class: Some("java/lang/IncompatibleClassChangeError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/null_pointer_exception.rs b/java_runtime/src/classes/java/lang/null_pointer_exception.rs index ecb5cdea..def52367 100644 --- a/java_runtime/src/classes/java/lang/null_pointer_exception.rs +++ b/java_runtime/src/classes/java/lang/null_pointer_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl NullPointerException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/number_format_exception.rs b/java_runtime/src/classes/java/lang/number_format_exception.rs index e1ad6eea..ee0e6b4a 100644 --- a/java_runtime/src/classes/java/lang/number_format_exception.rs +++ b/java_runtime/src/classes/java/lang/number_format_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl NumberFormatException { parent_class: Some("java/lang/IllegalArgumentException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/object.rs b/java_runtime/src/classes/java/lang/object.rs index 4fe013ce..4a760df2 100644 --- a/java_runtime/src/classes/java/lang/object.rs +++ b/java_runtime/src/classes/java/lang/object.rs @@ -7,7 +7,7 @@ use alloc::{boxed::Box, format, vec}; use dyn_clone::clone_box; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstance, ClassInstanceRef, Jvm, MonitorWaitTimeout, Result, runtime::JavaLangString}; use crate::{Runtime, RuntimeClassProto, RuntimeContext, SpawnCallback, classes::java::lang::String}; @@ -73,7 +73,7 @@ impl Object { JavaMethodProto::new("finalize", "()V", Self::finalize, MethodAccessFlags::PROTECTED), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/out_of_memory_error.rs b/java_runtime/src/classes/java/lang/out_of_memory_error.rs index 21f47459..aa35d904 100644 --- a/java_runtime/src/classes/java/lang/out_of_memory_error.rs +++ b/java_runtime/src/classes/java/lang/out_of_memory_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl OutOfMemoryError { parent_class: Some("java/lang/VirtualMachineError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/runnable.rs b/java_runtime/src/classes/java/lang/runnable.rs index 8340c8bd..479f4033 100644 --- a/java_runtime/src/classes/java/lang/runnable.rs +++ b/java_runtime/src/classes/java/lang/runnable.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use crate::RuntimeClassProto; @@ -14,7 +14,11 @@ impl Runnable { name: "java/lang/Runnable", parent_class: None, interfaces: vec![], - methods: vec![JavaMethodProto::new_abstract("run", "()V", Default::default())], + methods: vec![JavaMethodProto::new_abstract( + "run", + "()V", + MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT, + )], fields: vec![], access_flags: ClassAccessFlags::INTERFACE, } diff --git a/java_runtime/src/classes/java/lang/runtime.rs b/java_runtime/src/classes/java/lang/runtime.rs index 71b9a17c..66a79937 100644 --- a/java_runtime/src/classes/java/lang/runtime.rs +++ b/java_runtime/src/classes/java/lang/runtime.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext}; @@ -16,15 +16,25 @@ impl Runtime { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PRIVATE), JavaMethodProto::new("getRuntime", "()Ljava/lang/Runtime;", Self::get_runtime, MethodAccessFlags::STATIC), - JavaMethodProto::new("totalMemory", "()J", Self::total_memory, Default::default()), - JavaMethodProto::new("freeMemory", "()J", Self::free_memory, Default::default()), - JavaMethodProto::new("gc", "()V", Self::gc, Default::default()), + JavaMethodProto::new( + "totalMemory", + "()J", + Self::total_memory, + MethodAccessFlags::PUBLIC | MethodAccessFlags::NATIVE, + ), + JavaMethodProto::new( + "freeMemory", + "()J", + Self::free_memory, + MethodAccessFlags::PUBLIC | MethodAccessFlags::NATIVE, + ), + JavaMethodProto::new("gc", "()V", Self::gc, MethodAccessFlags::PUBLIC | MethodAccessFlags::NATIVE), JavaMethodProto::new("exit", "(I)V", Self::exit, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/lang/runtime_exception.rs b/java_runtime/src/classes/java/lang/runtime_exception.rs index fff1be52..6a2c2692 100644 --- a/java_runtime/src/classes/java/lang/runtime_exception.rs +++ b/java_runtime/src/classes/java/lang/runtime_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -18,18 +19,18 @@ impl RuntimeException { parent_class: Some("java/lang/Exception"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/Throwable;)V", Self::init_with_cause, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/Throwable;)V", Self::init_with_cause, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/lang/String;Ljava/lang/Throwable;)V", Self::init_with_message_and_cause, - Default::default(), + MethodAccessFlags::PUBLIC, ), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/security_exception.rs b/java_runtime/src/classes/java/lang/security_exception.rs index 526015e3..a962bac6 100644 --- a/java_runtime/src/classes/java/lang/security_exception.rs +++ b/java_runtime/src/classes/java/lang/security_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl SecurityException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/string.rs b/java_runtime/src/classes/java/lang/string.rs index 38f18a1b..7d46dcbc 100644 --- a/java_runtime/src/classes/java/lang/string.rs +++ b/java_runtime/src/classes/java/lang/string.rs @@ -34,28 +34,38 @@ impl String { parent_class: Some("java/lang/Object"), interfaces: vec!["java/io/Serializable", "java/lang/Comparable", "java/lang/CharSequence"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init_empty, Default::default()), - JavaMethodProto::new("", "([B)V", Self::init_with_byte_array, Default::default()), - JavaMethodProto::new("", "([C)V", Self::init_with_char_array, Default::default()), - JavaMethodProto::new("", "([CII)V", Self::init_with_partial_char_array, Default::default()), - JavaMethodProto::new("", "(II[C)V", Self::init_with_shared_char_array, Default::default()), - JavaMethodProto::new("", "([BII)V", Self::init_with_partial_byte_array, Default::default()), + JavaMethodProto::new("", "()V", Self::init_empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "([B)V", Self::init_with_byte_array, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "([C)V", Self::init_with_char_array, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "([CII)V", Self::init_with_partial_char_array, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(II[C)V", Self::init_with_shared_char_array, MethodAccessFlags::empty()), + JavaMethodProto::new("", "([BII)V", Self::init_with_partial_byte_array, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "([BLjava/lang/String;)V", Self::init_with_byte_array_charset, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "", "([BIILjava/lang/String;)V", Self::init_with_partial_byte_array_charset, - Default::default(), + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_string, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "", + "(Ljava/lang/StringBuffer;)V", + Self::init_with_string_buffer, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "equalsIgnoreCase", + "(Ljava/lang/String;)Z", + Self::equals_ignore_case, + MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_string, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/StringBuffer;)V", Self::init_with_string_buffer, Default::default()), - JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, Default::default()), - JavaMethodProto::new("equalsIgnoreCase", "(Ljava/lang/String;)Z", Self::equals_ignore_case, Default::default()), JavaMethodProto::new("compareTo", "(Ljava/lang/String;)I", Self::compare_to, MethodAccessFlags::PUBLIC), JavaMethodProto::new("compareTo", "(Ljava/lang/Object;)I", Self::compare_to, MethodAccessFlags::PUBLIC), JavaMethodProto::new( @@ -64,38 +74,43 @@ impl String { Self::compare_to_ignore_case, MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("hashCode", "()I", Self::hash_code, Default::default()), - JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, Default::default()), - JavaMethodProto::new("charAt", "(I)C", Self::char_at, Default::default()), - JavaMethodProto::new("getBytes", "()[B", Self::get_bytes, Default::default()), - JavaMethodProto::new("getBytes", "(Ljava/lang/String;)[B", Self::get_bytes_charset, Default::default()), - JavaMethodProto::new("getChars", "(II[CI)V", Self::get_chars, Default::default()), - JavaMethodProto::new("toCharArray", "()[C", Self::to_char_array, Default::default()), - JavaMethodProto::new("toUpperCase", "()Ljava/lang/String;", Self::to_upper_case, Default::default()), + JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("charAt", "(I)C", Self::char_at, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getBytes", "()[B", Self::get_bytes, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getBytes", "(Ljava/lang/String;)[B", Self::get_bytes_charset, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getChars", "(II[CI)V", Self::get_chars, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("toCharArray", "()[C", Self::to_char_array, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("toUpperCase", "()Ljava/lang/String;", Self::to_upper_case, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "toUpperCase", "(Ljava/util/Locale;)Ljava/lang/String;", Self::to_upper_case_locale, MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("toLowerCase", "()Ljava/lang/String;", Self::to_lower_case, Default::default()), + JavaMethodProto::new("toLowerCase", "()Ljava/lang/String;", Self::to_lower_case, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "toLowerCase", "(Ljava/util/Locale;)Ljava/lang/String;", Self::to_lower_case_locale, MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("length", "()I", Self::length, Default::default()), - JavaMethodProto::new("concat", "(Ljava/lang/String;)Ljava/lang/String;", Self::concat, Default::default()), - JavaMethodProto::new("substring", "(I)Ljava/lang/String;", Self::substring, Default::default()), - JavaMethodProto::new("substring", "(II)Ljava/lang/String;", Self::substring_with_end, Default::default()), + JavaMethodProto::new("length", "()I", Self::length, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "concat", + "(Ljava/lang/String;)Ljava/lang/String;", + Self::concat, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new("substring", "(I)Ljava/lang/String;", Self::substring, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("substring", "(II)Ljava/lang/String;", Self::substring_with_end, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "subSequence", "(II)Ljava/lang/CharSequence;", Self::sub_sequence, MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("replace", "(CC)Ljava/lang/String;", Self::replace, Default::default()), + JavaMethodProto::new("replace", "(CC)Ljava/lang/String;", Self::replace, MethodAccessFlags::PUBLIC), JavaMethodProto::new("matches", "(Ljava/lang/String;)Z", Self::matches, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "replaceFirst", @@ -134,7 +149,12 @@ impl String { Self::region_matches_case_sensitive, MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("regionMatches", "(ZILjava/lang/String;II)Z", Self::region_matches, Default::default()), + JavaMethodProto::new( + "regionMatches", + "(ZILjava/lang/String;II)Z", + Self::region_matches, + MethodAccessFlags::PUBLIC, + ), JavaMethodProto::new("valueOf", "(Z)Ljava/lang/String;", Self::value_of_boolean, MethodAccessFlags::STATIC), JavaMethodProto::new("valueOf", "(C)Ljava/lang/String;", Self::value_of_char, MethodAccessFlags::STATIC), JavaMethodProto::new("valueOf", "(I)Ljava/lang/String;", Self::value_of_integer, MethodAccessFlags::STATIC), @@ -164,12 +184,12 @@ impl String { Self::value_of_object, MethodAccessFlags::STATIC, ), - JavaMethodProto::new("indexOf", "(I)I", Self::index_of, Default::default()), - JavaMethodProto::new("indexOf", "(II)I", Self::index_of_from, Default::default()), - JavaMethodProto::new("indexOf", "(Ljava/lang/String;)I", Self::index_of_string, Default::default()), - JavaMethodProto::new("indexOf", "(Ljava/lang/String;I)I", Self::index_of_string_from, Default::default()), - JavaMethodProto::new("lastIndexOf", "(I)I", Self::last_index_of, Default::default()), - JavaMethodProto::new("lastIndexOf", "(II)I", Self::last_index_of_from, Default::default()), + JavaMethodProto::new("indexOf", "(I)I", Self::index_of, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("indexOf", "(II)I", Self::index_of_from, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("indexOf", "(Ljava/lang/String;)I", Self::index_of_string, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("indexOf", "(Ljava/lang/String;I)I", Self::index_of_string_from, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("lastIndexOf", "(I)I", Self::last_index_of, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("lastIndexOf", "(II)I", Self::last_index_of_from, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "lastIndexOf", "(Ljava/lang/String;)I", @@ -194,11 +214,21 @@ impl String { Self::copy_value_of_range, MethodAccessFlags::PUBLIC | MethodAccessFlags::STATIC, ), - JavaMethodProto::new("trim", "()Ljava/lang/String;", Self::trim, Default::default()), - JavaMethodProto::new("startsWith", "(Ljava/lang/String;)Z", Self::starts_with, Default::default()), - JavaMethodProto::new("startsWith", "(Ljava/lang/String;I)Z", Self::starts_with_offset, Default::default()), - JavaMethodProto::new("endsWith", "(Ljava/lang/String;)Z", Self::ends_with, Default::default()), - JavaMethodProto::new("intern", "()Ljava/lang/String;", Self::intern, Default::default()), + JavaMethodProto::new("trim", "()Ljava/lang/String;", Self::trim, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("startsWith", "(Ljava/lang/String;)Z", Self::starts_with, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "startsWith", + "(Ljava/lang/String;I)Z", + Self::starts_with_offset, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new("endsWith", "(Ljava/lang/String;)Z", Self::ends_with, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "intern", + "()Ljava/lang/String;", + Self::intern, + MethodAccessFlags::PUBLIC | MethodAccessFlags::NATIVE, + ), ], fields: vec![ JavaFieldProto::new("value", "[C", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL), diff --git a/java_runtime/src/classes/java/lang/string_index_out_of_bounds_exception.rs b/java_runtime/src/classes/java/lang/string_index_out_of_bounds_exception.rs index 442d3907..684b172a 100644 --- a/java_runtime/src/classes/java/lang/string_index_out_of_bounds_exception.rs +++ b/java_runtime/src/classes/java/lang/string_index_out_of_bounds_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl StringIndexOutOfBoundsException { parent_class: Some("java/lang/IndexOutOfBoundsException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/system.rs b/java_runtime/src/classes/java/lang/system.rs index 1b9a51b4..b21dc6f9 100644 --- a/java_runtime/src/classes/java/lang/system.rs +++ b/java_runtime/src/classes/java/lang/system.rs @@ -3,7 +3,7 @@ use alloc::{string::String as RustString, vec, vec::Vec}; use jvm::{JavaValue, runtime::JavaLangString}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{ @@ -107,7 +107,7 @@ impl System { ), JavaFieldProto::new("props", "Ljava/util/Properties;", FieldAccessFlags::PRIVATE | FieldAccessFlags::STATIC), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/lang/thread.rs b/java_runtime/src/classes/java/lang/thread.rs index 907b217e..46608df6 100644 --- a/java_runtime/src/classes/java/lang/thread.rs +++ b/java_runtime/src/classes/java/lang/thread.rs @@ -110,7 +110,7 @@ impl Thread { MethodAccessFlags::PUBLIC | MethodAccessFlags::NATIVE | MethodAccessFlags::STATIC, ), // rustjava internal - JavaMethodProto::new("", "(Z)V", Self::init_internal, Default::default()), + JavaMethodProto::new("", "(Z)V", Self::init_internal, MethodAccessFlags::PRIVATE), ], fields: vec![ JavaFieldProto::new( diff --git a/java_runtime/src/classes/java/lang/throwable.rs b/java_runtime/src/classes/java/lang/throwable.rs index d74ddbfb..5d231258 100644 --- a/java_runtime/src/classes/java/lang/throwable.rs +++ b/java_runtime/src/classes/java/lang/throwable.rs @@ -1,7 +1,7 @@ use alloc::{boxed::Box, format, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstance, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -72,9 +72,9 @@ impl Throwable { ), ], fields: vec![ - JavaFieldProto::new("detailMessage", "Ljava/lang/String;", Default::default()), - JavaFieldProto::new("cause", "Ljava/lang/Throwable;", Default::default()), - JavaFieldProto::new("stackTrace", "[Ljava/lang/String;", Default::default()), + JavaFieldProto::new("detailMessage", "Ljava/lang/String;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("cause", "Ljava/lang/Throwable;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("stackTrace", "[Ljava/lang/String;", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/src/classes/java/lang/unsatisfied_link_error.rs b/java_runtime/src/classes/java/lang/unsatisfied_link_error.rs index 9650a54c..e74da04b 100644 --- a/java_runtime/src/classes/java/lang/unsatisfied_link_error.rs +++ b/java_runtime/src/classes/java/lang/unsatisfied_link_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl UnsatisfiedLinkError { parent_class: Some("java/lang/LinkageError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/unsupported_class_version_error.rs b/java_runtime/src/classes/java/lang/unsupported_class_version_error.rs index 18c354c1..bdaa2f9c 100644 --- a/java_runtime/src/classes/java/lang/unsupported_class_version_error.rs +++ b/java_runtime/src/classes/java/lang/unsupported_class_version_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl UnsupportedClassVersionError { parent_class: Some("java/lang/ClassFormatError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/unsupported_operation_exception.rs b/java_runtime/src/classes/java/lang/unsupported_operation_exception.rs index 402847a7..376edecb 100644 --- a/java_runtime/src/classes/java/lang/unsupported_operation_exception.rs +++ b/java_runtime/src/classes/java/lang/unsupported_operation_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl UnsupportedOperationException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/verify_error.rs b/java_runtime/src/classes/java/lang/verify_error.rs index b1424668..3542f033 100644 --- a/java_runtime/src/classes/java/lang/verify_error.rs +++ b/java_runtime/src/classes/java/lang/verify_error.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl VerifyError { parent_class: Some("java/lang/LinkageError"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/lang/virtual_machine_error.rs b/java_runtime/src/classes/java/lang/virtual_machine_error.rs index e0b58539..325e494f 100644 --- a/java_runtime/src/classes/java/lang/virtual_machine_error.rs +++ b/java_runtime/src/classes/java/lang/virtual_machine_error.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -16,8 +16,8 @@ impl VirtualMachineError { parent_class: Some("java/lang/Error"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], access_flags: ClassAccessFlags::ABSTRACT, diff --git a/java_runtime/src/classes/java/net/jar_url_connection.rs b/java_runtime/src/classes/java/net/jar_url_connection.rs index 21971cb4..54ad4172 100644 --- a/java_runtime/src/classes/java/net/jar_url_connection.rs +++ b/java_runtime/src/classes/java/net/jar_url_connection.rs @@ -1,7 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -37,8 +37,8 @@ impl JarURLConnection { ), ], fields: vec![ - JavaFieldProto::new("fileUrl", "Ljava/net/URL;", Default::default()), - JavaFieldProto::new("entry", "Ljava/lang/String;", Default::default()), + JavaFieldProto::new("fileUrl", "Ljava/net/URL;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("entry", "Ljava/lang/String;", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::ABSTRACT, } diff --git a/java_runtime/src/classes/java/net/malformed_url_exception.rs b/java_runtime/src/classes/java/net/malformed_url_exception.rs index 1b1215c4..cfb606a6 100644 --- a/java_runtime/src/classes/java/net/malformed_url_exception.rs +++ b/java_runtime/src/classes/java/net/malformed_url_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl MalformedURLException { parent_class: Some("java/io/IOException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/net/unknown_service_exception.rs b/java_runtime/src/classes/java/net/unknown_service_exception.rs index 03ee5827..9f17beb9 100644 --- a/java_runtime/src/classes/java/net/unknown_service_exception.rs +++ b/java_runtime/src/classes/java/net/unknown_service_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl UnknownServiceException { parent_class: Some("java/io/IOException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/net/url.rs b/java_runtime/src/classes/java/net/url.rs index bfda6e65..74556491 100644 --- a/java_runtime/src/classes/java/net/url.rs +++ b/java_runtime/src/classes/java/net/url.rs @@ -1,6 +1,7 @@ use alloc::{format, vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -22,52 +23,62 @@ impl URL { parent_class: Some("java/lang/Object"), interfaces: vec!["java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_spec, Default::default()), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_spec, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/net/URL;Ljava/lang/String;)V", Self::init_with_context_spec, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "", "(Ljava/net/URL;Ljava/lang/String;Ljava/net/URLStreamHandler;)V", Self::init_with_context_spec_handler, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", Self::init_with_protocol_host_file, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "", "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/net/URLStreamHandler;)V", Self::init_with_protocol_host_port_file_handler, - Default::default(), + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new( + "openConnection", + "()Ljava/net/URLConnection;", + Self::open_connection, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new( + "openStream", + "()Ljava/io/InputStream;", + Self::open_stream, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, ), - JavaMethodProto::new("openConnection", "()Ljava/net/URLConnection;", Self::open_connection, Default::default()), - JavaMethodProto::new("openStream", "()Ljava/io/InputStream;", Self::open_stream, Default::default()), JavaMethodProto::new( "set", "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V", Self::set, - Default::default(), + MethodAccessFlags::PROTECTED, ), - JavaMethodProto::new("getPort", "()I", Self::get_port, Default::default()), - JavaMethodProto::new("getProtocol", "()Ljava/lang/String;", Self::get_protocol, Default::default()), - JavaMethodProto::new("getHost", "()Ljava/lang/String;", Self::get_host, Default::default()), - JavaMethodProto::new("getFile", "()Ljava/lang/String;", Self::get_file, Default::default()), + JavaMethodProto::new("getPort", "()I", Self::get_port, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getProtocol", "()Ljava/lang/String;", Self::get_protocol, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getHost", "()Ljava/lang/String;", Self::get_host, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getFile", "()Ljava/lang/String;", Self::get_file, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("protocol", "Ljava/lang/String;", Default::default()), - JavaFieldProto::new("host", "Ljava/lang/String;", Default::default()), - JavaFieldProto::new("port", "I", Default::default()), - JavaFieldProto::new("file", "Ljava/lang/String;", Default::default()), - JavaFieldProto::new("handler", "Ljava/net/URLStreamHandler;", Default::default()), + JavaFieldProto::new("protocol", "Ljava/lang/String;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("host", "Ljava/lang/String;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("port", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("file", "Ljava/lang/String;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("handler", "Ljava/net/URLStreamHandler;", FieldAccessFlags::TRANSIENT), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/net/url_class_loader.rs b/java_runtime/src/classes/java/net/url_class_loader.rs index 49b9c092..c817b5b1 100644 --- a/java_runtime/src/classes/java/net/url_class_loader.rs +++ b/java_runtime/src/classes/java/net/url_class_loader.rs @@ -1,7 +1,7 @@ use alloc::{format, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ Array, ClassInstanceRef, Jvm, Result, runtime::{JavaIoInputStream, JavaLangString}, @@ -45,8 +45,8 @@ impl URLClassLoader { MethodAccessFlags::PUBLIC, ), ], - fields: vec![JavaFieldProto::new("urls", "[Ljava/net/URL;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("urls", "[Ljava/net/URL;", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/net/url_connection.rs b/java_runtime/src/classes/java/net/url_connection.rs index a4b53cf0..429d66b8 100644 --- a/java_runtime/src/classes/java/net/url_connection.rs +++ b/java_runtime/src/classes/java/net/url_connection.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -27,8 +27,8 @@ impl URLConnection { MethodAccessFlags::PUBLIC, ), ], - fields: vec![JavaFieldProto::new("url", "Ljava/net/URL;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("url", "Ljava/net/URL;", FieldAccessFlags::PROTECTED)], + access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::ABSTRACT, } } diff --git a/java_runtime/src/classes/java/util/abstract_list.rs b/java_runtime/src/classes/java/util/abstract_list.rs index 6b497668..afbde8d8 100644 --- a/java_runtime/src/classes/java/util/abstract_list.rs +++ b/java_runtime/src/classes/java/util/abstract_list.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -258,17 +258,17 @@ impl AbstractListItr { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Iterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/List;I)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/List;I)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "()V", Self::remove, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("list", "Ljava/util/List;", Default::default()), - JavaFieldProto::new("cursor", "I", Default::default()), - JavaFieldProto::new("lastReturned", "I", Default::default()), + JavaFieldProto::new("list", "Ljava/util/List;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("cursor", "I", FieldAccessFlags::empty()), + JavaFieldProto::new("lastReturned", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -278,7 +278,7 @@ impl AbstractListItr { parent_class: Some("java/util/AbstractList$Itr"), interfaces: vec!["java/util/ListIterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/List;I)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/List;I)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasPrevious", "()Z", Self::has_previous, MethodAccessFlags::PUBLIC), JavaMethodProto::new("previous", "()Ljava/lang/Object;", Self::previous, MethodAccessFlags::PUBLIC), JavaMethodProto::new("nextIndex", "()I", Self::next_index, MethodAccessFlags::PUBLIC), @@ -287,7 +287,7 @@ impl AbstractListItr { JavaMethodProto::new("add", "(Ljava/lang/Object;)V", Self::add, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/abstract_list_sub_list.rs b/java_runtime/src/classes/java/util/abstract_list_sub_list.rs index 1938540c..54d9f5ff 100644 --- a/java_runtime/src/classes/java/util/abstract_list_sub_list.rs +++ b/java_runtime/src/classes/java/util/abstract_list_sub_list.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -20,7 +20,7 @@ impl AbstractListSubList { "", "(Ljava/util/List;Ljava/util/AbstractList$SubList;II)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("get", "(I)Ljava/lang/Object;", Self::get, MethodAccessFlags::PUBLIC), @@ -50,12 +50,16 @@ impl AbstractListSubList { JavaMethodProto::new("subList", "(II)Ljava/util/List;", Self::sub_list, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("root", "Ljava/util/List;", Default::default()), - JavaFieldProto::new("parent", "Ljava/util/AbstractList$SubList;", Default::default()), - JavaFieldProto::new("offset", "I", Default::default()), - JavaFieldProto::new("size", "I", Default::default()), + JavaFieldProto::new("root", "Ljava/util/List;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new( + "parent", + "Ljava/util/AbstractList$SubList;", + FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, + ), + JavaFieldProto::new("offset", "I", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL), + JavaFieldProto::new("size", "I", FieldAccessFlags::PROTECTED), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/array_list.rs b/java_runtime/src/classes/java/util/array_list.rs index 4588c999..389f6f44 100644 --- a/java_runtime/src/classes/java/util/array_list.rs +++ b/java_runtime/src/classes/java/util/array_list.rs @@ -1,7 +1,7 @@ use alloc::{format, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -51,8 +51,8 @@ impl ArrayList { ), ], fields: vec![ - JavaFieldProto::new("elementData", "[Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("size", "I", Default::default()), + JavaFieldProto::new("elementData", "[Ljava/lang/Object;", FieldAccessFlags::TRANSIENT), + JavaFieldProto::new("size", "I", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/src/classes/java/util/array_list_itr.rs b/java_runtime/src/classes/java/util/array_list_itr.rs index 4bdf077e..a71e2752 100644 --- a/java_runtime/src/classes/java/util/array_list_itr.rs +++ b/java_runtime/src/classes/java/util/array_list_itr.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,17 +16,17 @@ impl ArrayListItr { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Iterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/List;I)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/List;I)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "()V", Self::remove, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("list", "Ljava/util/List;", Default::default()), - JavaFieldProto::new("cursor", "I", Default::default()), - JavaFieldProto::new("lastReturned", "I", Default::default()), + JavaFieldProto::new("list", "Ljava/util/List;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("cursor", "I", FieldAccessFlags::empty()), + JavaFieldProto::new("lastReturned", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -36,7 +36,7 @@ impl ArrayListItr { parent_class: Some("java/util/ArrayList$Itr"), interfaces: vec!["java/util/ListIterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/List;I)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/List;I)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasPrevious", "()Z", Self::has_previous, MethodAccessFlags::PUBLIC), JavaMethodProto::new("previous", "()Ljava/lang/Object;", Self::previous, MethodAccessFlags::PUBLIC), JavaMethodProto::new("nextIndex", "()I", Self::next_index, MethodAccessFlags::PUBLIC), @@ -45,7 +45,7 @@ impl ArrayListItr { JavaMethodProto::new("add", "(Ljava/lang/Object;)V", Self::add, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/arrays_array_list.rs b/java_runtime/src/classes/java/util/arrays_array_list.rs index cc4594c5..b1eb07cd 100644 --- a/java_runtime/src/classes/java/util/arrays_array_list.rs +++ b/java_runtime/src/classes/java/util/arrays_array_list.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, AsClassInstance, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl ArraysArrayList { parent_class: Some("java/util/AbstractList"), interfaces: vec!["java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "([Ljava/lang/Object;)V", Self::init, Default::default()), + JavaMethodProto::new("", "([Ljava/lang/Object;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("get", "(I)Ljava/lang/Object;", Self::get, MethodAccessFlags::PUBLIC), JavaMethodProto::new("set", "(ILjava/lang/Object;)Ljava/lang/Object;", Self::set, MethodAccessFlags::PUBLIC), @@ -31,7 +31,7 @@ impl ArraysArrayList { "[Ljava/lang/Object;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, )], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/calendar.rs b/java_runtime/src/classes/java/util/calendar.rs index b66b23f3..386a760c 100644 --- a/java_runtime/src/classes/java/util/calendar.rs +++ b/java_runtime/src/classes/java/util/calendar.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -63,10 +63,10 @@ impl Calendar { JavaMethodProto::new_abstract("computeFields", "()V", MethodAccessFlags::PROTECTED | MethodAccessFlags::ABSTRACT), ], fields: vec![ - JavaFieldProto::new("time", "J", Default::default()), - JavaFieldProto::new("fields", "[I", Default::default()), - JavaFieldProto::new("timeZone", "Ljava/util/TimeZone;", Default::default()), - JavaFieldProto::new("lenient", "Z", Default::default()), + JavaFieldProto::new("time", "J", FieldAccessFlags::PROTECTED), + JavaFieldProto::new("fields", "[I", FieldAccessFlags::PROTECTED), + JavaFieldProto::new("timeZone", "Ljava/util/TimeZone;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("lenient", "Z", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::ABSTRACT, } diff --git a/java_runtime/src/classes/java/util/collections_copies_list.rs b/java_runtime/src/classes/java/util/collections_copies_list.rs index 05bbeb05..f06b448e 100644 --- a/java_runtime/src/classes/java/util/collections_copies_list.rs +++ b/java_runtime/src/classes/java/util/collections_copies_list.rs @@ -16,7 +16,7 @@ impl CollectionsCopiesList { parent_class: Some("java/util/AbstractList"), interfaces: vec!["java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "(ILjava/lang/Object;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(ILjava/lang/Object;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), JavaMethodProto::new("indexOf", "(Ljava/lang/Object;)I", Self::index_of, MethodAccessFlags::PUBLIC), diff --git a/java_runtime/src/classes/java/util/collections_singleton_set.rs b/java_runtime/src/classes/java/util/collections_singleton_set.rs index eaa96bac..c39008e2 100644 --- a/java_runtime/src/classes/java/util/collections_singleton_set.rs +++ b/java_runtime/src/classes/java/util/collections_singleton_set.rs @@ -16,7 +16,7 @@ impl CollectionsSingletonSet { parent_class: Some("java/util/AbstractSet"), interfaces: vec!["java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/lang/Object;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/lang/Object;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_collection.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_collection.rs index 3ae7adb1..09d812b5 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_collection.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_collection.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableCollection { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Collection", "java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Collection;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Collection;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), @@ -38,7 +38,7 @@ impl CollectionsUnmodifiableCollection { JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("c", "Ljava/util/Collection;", FieldAccessFlags::FINAL)], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_collection_iterator.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_collection_iterator.rs index bcfadf79..c18731b0 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_collection_iterator.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_collection_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableCollectionIterator { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Iterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Iterator;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Iterator;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "()V", Self::remove, MethodAccessFlags::PUBLIC), @@ -26,7 +26,7 @@ impl CollectionsUnmodifiableCollectionIterator { "Ljava/util/Iterator;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, )], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_list.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_list.rs index 39c5e55d..66688dd9 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_list.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_list.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableList { parent_class: Some("java/util/Collections$UnmodifiableCollection"), interfaces: vec!["java/util/List"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/List;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/List;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), JavaMethodProto::new("get", "(I)Ljava/lang/Object;", Self::get, MethodAccessFlags::PUBLIC), @@ -41,7 +41,7 @@ impl CollectionsUnmodifiableList { JavaMethodProto::new("remove", "(I)Ljava/lang/Object;", Self::remove, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("list", "Ljava/util/List;", FieldAccessFlags::FINAL)], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_list_iterator.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_list_iterator.rs index a4d8d654..1f55c076 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_list_iterator.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_list_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableListIterator { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/ListIterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/ListIterator;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/ListIterator;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("hasPrevious", "()Z", Self::has_previous, MethodAccessFlags::PUBLIC), @@ -32,7 +32,7 @@ impl CollectionsUnmodifiableListIterator { "Ljava/util/ListIterator;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, )], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_map.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_map.rs index 768591dc..522f61f5 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_map.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_map.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableMap { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Map", "java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Map;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Map;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), JavaMethodProto::new("containsKey", "(Ljava/lang/Object;)Z", Self::contains_key, MethodAccessFlags::PUBLIC), @@ -53,7 +53,7 @@ impl CollectionsUnmodifiableMap { FieldAccessFlags::PRIVATE | FieldAccessFlags::TRANSIENT, ), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry.rs index 550b7953..6bc2ea7c 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableMapEntry { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Map$Entry"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Map$Entry;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Map$Entry;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("getKey", "()Ljava/lang/Object;", Self::get_key, MethodAccessFlags::PUBLIC), JavaMethodProto::new("getValue", "()Ljava/lang/Object;", Self::get_value, MethodAccessFlags::PUBLIC), JavaMethodProto::new( @@ -34,7 +34,7 @@ impl CollectionsUnmodifiableMapEntry { "Ljava/util/Map$Entry;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, )], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set.rs index caffe77c..f8d783b5 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set.rs @@ -1,7 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, AsClassInstance, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableMapEntrySet { parent_class: Some("java/util/Collections$UnmodifiableSet"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Set;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Set;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), JavaMethodProto::new("toArray", "()[Ljava/lang/Object;", Self::to_array, MethodAccessFlags::PUBLIC), JavaMethodProto::new( @@ -30,7 +30,7 @@ impl CollectionsUnmodifiableMapEntrySet { JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set_iterator.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set_iterator.rs index ed25a5f1..05e05e06 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set_iterator.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_map_entry_set_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableMapEntrySetIterator { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Iterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Iterator;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Iterator;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "()V", Self::remove, MethodAccessFlags::PUBLIC), @@ -26,7 +26,7 @@ impl CollectionsUnmodifiableMapEntrySetIterator { "Ljava/util/Iterator;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, )], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_set.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_set.rs index 5a3baafe..bf158f54 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_set.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_set.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,12 +16,12 @@ impl CollectionsUnmodifiableSet { parent_class: Some("java/util/Collections$UnmodifiableCollection"), interfaces: vec!["java/util/Set", "java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Set;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Set;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_map.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_map.rs index 4fbe9a06..2d0bef01 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_map.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_map.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableSortedMap { parent_class: Some("java/util/Collections$UnmodifiableMap"), interfaces: vec!["java/util/SortedMap", "java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("comparator", "()Ljava/util/Comparator;", Self::comparator, MethodAccessFlags::PUBLIC), JavaMethodProto::new("firstKey", "()Ljava/lang/Object;", Self::first_key, MethodAccessFlags::PUBLIC), JavaMethodProto::new("lastKey", "()Ljava/lang/Object;", Self::last_key, MethodAccessFlags::PUBLIC), @@ -44,7 +44,7 @@ impl CollectionsUnmodifiableSortedMap { "Ljava/util/SortedMap;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, )], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_set.rs b/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_set.rs index f4082d74..c93e5617 100644 --- a/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_set.rs +++ b/java_runtime/src/classes/java/util/collections_unmodifiable_sorted_set.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl CollectionsUnmodifiableSortedSet { parent_class: Some("java/util/Collections$UnmodifiableSet"), interfaces: vec!["java/util/SortedSet", "java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/SortedSet;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/SortedSet;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("comparator", "()Ljava/util/Comparator;", Self::comparator, MethodAccessFlags::PUBLIC), JavaMethodProto::new("first", "()Ljava/lang/Object;", Self::first, MethodAccessFlags::PUBLIC), JavaMethodProto::new("last", "()Ljava/lang/Object;", Self::last, MethodAccessFlags::PUBLIC), @@ -44,7 +44,7 @@ impl CollectionsUnmodifiableSortedSet { "Ljava/util/SortedSet;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL, )], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/dictionary.rs b/java_runtime/src/classes/java/util/dictionary.rs index f1fdff97..632a31de 100644 --- a/java_runtime/src/classes/java/util/dictionary.rs +++ b/java_runtime/src/classes/java/util/dictionary.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext}; @@ -15,7 +15,7 @@ impl Dictionary { name: "java/util/Dictionary", parent_class: Some("java/lang/Object"), interfaces: vec![], - methods: vec![JavaMethodProto::new("", "()V", Self::init, Default::default())], + methods: vec![JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC)], fields: vec![], access_flags: ClassAccessFlags::ABSTRACT, } diff --git a/java_runtime/src/classes/java/util/empty_stack_exception.rs b/java_runtime/src/classes/java/util/empty_stack_exception.rs index ebdcdcbc..241f26a9 100644 --- a/java_runtime/src/classes/java/util/empty_stack_exception.rs +++ b/java_runtime/src/classes/java/util/empty_stack_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl EmptyStackException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/util/enumeration.rs b/java_runtime/src/classes/java/util/enumeration.rs index b288c438..7c1f667b 100644 --- a/java_runtime/src/classes/java/util/enumeration.rs +++ b/java_runtime/src/classes/java/util/enumeration.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use crate::RuntimeClassProto; @@ -15,8 +15,12 @@ impl Enumeration { parent_class: None, interfaces: vec![], methods: vec![ - JavaMethodProto::new_abstract("hasMoreElements", "()Z", Default::default()), - JavaMethodProto::new_abstract("nextElement", "()Ljava/lang/Object;", Default::default()), + JavaMethodProto::new_abstract("hasMoreElements", "()Z", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), + JavaMethodProto::new_abstract( + "nextElement", + "()Ljava/lang/Object;", + MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT, + ), ], fields: vec![], access_flags: ClassAccessFlags::INTERFACE, diff --git a/java_runtime/src/classes/java/util/hash_map.rs b/java_runtime/src/classes/java/util/hash_map.rs index 0d7fdfec..0bf5d3af 100644 --- a/java_runtime/src/classes/java/util/hash_map.rs +++ b/java_runtime/src/classes/java/util/hash_map.rs @@ -1,7 +1,7 @@ use alloc::{format, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -47,29 +47,39 @@ impl HashMap { JavaMethodProto::new("keySet", "()Ljava/util/Set;", Self::key_set, MethodAccessFlags::PUBLIC), JavaMethodProto::new("values", "()Ljava/util/Collection;", Self::values, MethodAccessFlags::PUBLIC), JavaMethodProto::new("entrySet", "()Ljava/util/Set;", Self::entry_set, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("initializeMap", "()V", Self::initialize_map, Default::default()), + JavaMethodProto::new("initializeMap", "()V", Self::initialize_map, MethodAccessFlags::empty()), JavaMethodProto::new( "storeNewEntry", "(ILjava/lang/Object;Ljava/lang/Object;I)V", Self::store_new_entry, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new( "insertNewEntry", "(ILjava/lang/Object;Ljava/lang/Object;I)V", Self::insert_new_entry, - Default::default(), + MethodAccessFlags::empty(), + ), + JavaMethodProto::new("keyIterator", "()Ljava/util/Iterator;", Self::key_iterator, MethodAccessFlags::empty()), + JavaMethodProto::new( + "valueIterator", + "()Ljava/util/Iterator;", + Self::value_iterator, + MethodAccessFlags::empty(), + ), + JavaMethodProto::new( + "entryIterator", + "()Ljava/util/Iterator;", + Self::entry_iterator, + MethodAccessFlags::empty(), ), - JavaMethodProto::new("keyIterator", "()Ljava/util/Iterator;", Self::key_iterator, Default::default()), - JavaMethodProto::new("valueIterator", "()Ljava/util/Iterator;", Self::value_iterator, Default::default()), - JavaMethodProto::new("entryIterator", "()Ljava/util/Iterator;", Self::entry_iterator, Default::default()), ], fields: vec![ - JavaFieldProto::new("table", "[Ljava/util/HashMap$Entry;", Default::default()), - JavaFieldProto::new("size", "I", Default::default()), - JavaFieldProto::new("threshold", "I", Default::default()), - JavaFieldProto::new("loadFactor", "F", Default::default()), - JavaFieldProto::new("modCount", "I", Default::default()), + JavaFieldProto::new("table", "[Ljava/util/HashMap$Entry;", FieldAccessFlags::TRANSIENT), + JavaFieldProto::new("size", "I", FieldAccessFlags::TRANSIENT), + JavaFieldProto::new("threshold", "I", FieldAccessFlags::empty()), + JavaFieldProto::new("loadFactor", "F", FieldAccessFlags::FINAL), + JavaFieldProto::new("modCount", "I", FieldAccessFlags::TRANSIENT), ], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/src/classes/java/util/hash_map_entry.rs b/java_runtime/src/classes/java/util/hash_map_entry.rs index 071db707..4c6614eb 100644 --- a/java_runtime/src/classes/java/util/hash_map_entry.rs +++ b/java_runtime/src/classes/java/util/hash_map_entry.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -22,7 +22,7 @@ impl HashMapEntry { "", "(ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Entry;)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new("getKey", "()Ljava/lang/Object;", Self::get_key, MethodAccessFlags::PUBLIC), JavaMethodProto::new("getValue", "()Ljava/lang/Object;", Self::get_value, MethodAccessFlags::PUBLIC), @@ -34,16 +34,16 @@ impl HashMapEntry { ), JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("onAccess", "(Ljava/util/HashMap;)V", Self::on_access, Default::default()), - JavaMethodProto::new("onRemoval", "(Ljava/util/HashMap;)V", Self::on_removal, Default::default()), + JavaMethodProto::new("onAccess", "(Ljava/util/HashMap;)V", Self::on_access, MethodAccessFlags::empty()), + JavaMethodProto::new("onRemoval", "(Ljava/util/HashMap;)V", Self::on_removal, MethodAccessFlags::empty()), ], fields: vec![ - JavaFieldProto::new("hash", "I", Default::default()), - JavaFieldProto::new("key", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("value", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("next", "Ljava/util/HashMap$Entry;", Default::default()), + JavaFieldProto::new("hash", "I", FieldAccessFlags::FINAL), + JavaFieldProto::new("key", "Ljava/lang/Object;", FieldAccessFlags::FINAL), + JavaFieldProto::new("value", "Ljava/lang/Object;", FieldAccessFlags::empty()), + JavaFieldProto::new("next", "Ljava/util/HashMap$Entry;", FieldAccessFlags::empty()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/hash_map_entry_iterator.rs b/java_runtime/src/classes/java/util/hash_map_entry_iterator.rs index b505fb8e..0960f7f3 100644 --- a/java_runtime/src/classes/java/util/hash_map_entry_iterator.rs +++ b/java_runtime/src/classes/java/util/hash_map_entry_iterator.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -14,9 +15,14 @@ impl HashMapEntryIterator { name: "java/util/HashMap$EntryIterator", parent_class: Some("java/util/HashMap$HashIterator"), interfaces: vec![], - methods: vec![JavaMethodProto::new("", "([Ljava/lang/Object;)V", Self::init, Default::default())], + methods: vec![JavaMethodProto::new( + "", + "([Ljava/lang/Object;)V", + Self::init, + MethodAccessFlags::empty(), + )], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/hash_map_entry_set.rs b/java_runtime/src/classes/java/util/hash_map_entry_set.rs index 28b8c826..05f1c949 100644 --- a/java_runtime/src/classes/java/util/hash_map_entry_set.rs +++ b/java_runtime/src/classes/java/util/hash_map_entry_set.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -18,16 +18,26 @@ impl HashMapEntrySet { parent_class: Some("java/util/AbstractSet"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/HashMap;)V", Self::init, Default::default()), - JavaMethodProto::new("size", "()I", Self::size, Default::default()), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), + JavaMethodProto::new("", "(Ljava/util/HashMap;)V", Self::init, MethodAccessFlags::empty()), + JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "contains", + "(Ljava/lang/Object;)Z", + Self::contains, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, Default::default()), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new( + "iterator", + "()Ljava/util/Iterator;", + Self::iterator, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), ], - fields: vec![JavaFieldProto::new("map", "Ljava/util/HashMap;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("map", "Ljava/util/HashMap;", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/hash_map_hash_iterator.rs b/java_runtime/src/classes/java/util/hash_map_hash_iterator.rs index d8ebc221..b875692c 100644 --- a/java_runtime/src/classes/java/util/hash_map_hash_iterator.rs +++ b/java_runtime/src/classes/java/util/hash_map_hash_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,14 +16,14 @@ impl HashMapHashIterator { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Iterator"], methods: vec![ - JavaMethodProto::new("", "([Ljava/lang/Object;)V", Self::init, Default::default()), - JavaMethodProto::new("hasNext", "()Z", Self::has_next, Default::default()), - JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, Default::default()), - JavaMethodProto::new("remove", "()V", Self::remove, Default::default()), + JavaMethodProto::new("", "([Ljava/lang/Object;)V", Self::init, MethodAccessFlags::empty()), + JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("remove", "()V", Self::remove, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), ], fields: vec![ - JavaFieldProto::new("elements", "[Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("index", "I", Default::default()), + JavaFieldProto::new("elements", "[Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("index", "I", FieldAccessFlags::empty()), ], access_flags: ClassAccessFlags::ABSTRACT, } diff --git a/java_runtime/src/classes/java/util/hash_map_key_iterator.rs b/java_runtime/src/classes/java/util/hash_map_key_iterator.rs index 8a6c5b0a..a7fb6998 100644 --- a/java_runtime/src/classes/java/util/hash_map_key_iterator.rs +++ b/java_runtime/src/classes/java/util/hash_map_key_iterator.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -14,9 +15,14 @@ impl HashMapKeyIterator { name: "java/util/HashMap$KeyIterator", parent_class: Some("java/util/HashMap$HashIterator"), interfaces: vec![], - methods: vec![JavaMethodProto::new("", "([Ljava/lang/Object;)V", Self::init, Default::default())], + methods: vec![JavaMethodProto::new( + "", + "([Ljava/lang/Object;)V", + Self::init, + MethodAccessFlags::empty(), + )], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/hash_map_key_set.rs b/java_runtime/src/classes/java/util/hash_map_key_set.rs index bb29d006..60da68f6 100644 --- a/java_runtime/src/classes/java/util/hash_map_key_set.rs +++ b/java_runtime/src/classes/java/util/hash_map_key_set.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -17,16 +18,31 @@ impl HashMapKeySet { parent_class: Some("java/util/AbstractSet"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/HashMap;)V", Self::init, Default::default()), - JavaMethodProto::new("size", "()I", Self::size, Default::default()), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), - JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, Default::default()), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, Default::default()), + JavaMethodProto::new("", "(Ljava/util/HashMap;)V", Self::init, MethodAccessFlags::empty()), + JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "contains", + "(Ljava/lang/Object;)Z", + Self::contains, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new( + "remove", + "(Ljava/lang/Object;)Z", + Self::remove, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new( + "iterator", + "()Ljava/util/Iterator;", + Self::iterator, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), ], - fields: vec![JavaFieldProto::new("map", "Ljava/util/HashMap;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("map", "Ljava/util/HashMap;", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/hash_map_value_iterator.rs b/java_runtime/src/classes/java/util/hash_map_value_iterator.rs index fe56f286..3b7ea9e6 100644 --- a/java_runtime/src/classes/java/util/hash_map_value_iterator.rs +++ b/java_runtime/src/classes/java/util/hash_map_value_iterator.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -14,9 +15,14 @@ impl HashMapValueIterator { name: "java/util/HashMap$ValueIterator", parent_class: Some("java/util/HashMap$HashIterator"), interfaces: vec![], - methods: vec![JavaMethodProto::new("", "([Ljava/lang/Object;)V", Self::init, Default::default())], + methods: vec![JavaMethodProto::new( + "", + "([Ljava/lang/Object;)V", + Self::init, + MethodAccessFlags::empty(), + )], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/hash_map_values.rs b/java_runtime/src/classes/java/util/hash_map_values.rs index bf9c9de3..0cf98e8f 100644 --- a/java_runtime/src/classes/java/util/hash_map_values.rs +++ b/java_runtime/src/classes/java/util/hash_map_values.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -18,16 +18,26 @@ impl HashMapValues { parent_class: Some("java/util/AbstractCollection"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/HashMap;)V", Self::init, Default::default()), - JavaMethodProto::new("size", "()I", Self::size, Default::default()), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), + JavaMethodProto::new("", "(Ljava/util/HashMap;)V", Self::init, MethodAccessFlags::empty()), + JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "contains", + "(Ljava/lang/Object;)Z", + Self::contains, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, Default::default()), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL), + JavaMethodProto::new( + "iterator", + "()Ljava/util/Iterator;", + Self::iterator, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, + ), ], - fields: vec![JavaFieldProto::new("map", "Ljava/util/HashMap;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("map", "Ljava/util/HashMap;", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/hash_set.rs b/java_runtime/src/classes/java/util/hash_set.rs index 709e3cc0..dfd9b2a4 100644 --- a/java_runtime/src/classes/java/util/hash_set.rs +++ b/java_runtime/src/classes/java/util/hash_set.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -20,26 +20,26 @@ impl HashSet { parent_class: Some("java/util/AbstractSet"), interfaces: vec!["java/lang/Cloneable", "java/io/Serializable"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(I)V", Self::init_with_capacity, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(I)V", Self::init_with_capacity, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/util/Collection;)V", Self::init_from_collection, MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("add", "(Ljava/lang/Object;)Z", Self::add, Default::default()), - JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), - JavaMethodProto::new("size", "()I", Self::size, Default::default()), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, Default::default()), - JavaMethodProto::new("toArray", "()[Ljava/lang/Object;", Self::to_array, Default::default()), + JavaMethodProto::new("add", "(Ljava/lang/Object;)Z", Self::add, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("toArray", "()[Ljava/lang/Object;", Self::to_array, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("map", "Ljava/util/HashMap;", Default::default()), - JavaFieldProto::new("present", "Ljava/lang/Object;", Default::default()), + JavaFieldProto::new("map", "Ljava/util/HashMap;", FieldAccessFlags::TRANSIENT), + JavaFieldProto::new("present", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL), ], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/src/classes/java/util/hashtable.rs b/java_runtime/src/classes/java/util/hashtable.rs index f59fa358..3e7917dd 100644 --- a/java_runtime/src/classes/java/util/hashtable.rs +++ b/java_runtime/src/classes/java/util/hashtable.rs @@ -1,7 +1,7 @@ use alloc::{string::String as RustString, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaError, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -108,10 +108,14 @@ impl Hashtable { ), ], fields: vec![ - JavaFieldProto::new("table", "[Ljava/util/Hashtable$Entry;", Default::default()), - JavaFieldProto::new("count", "I", Default::default()), - JavaFieldProto::new("threshold", "I", Default::default()), - JavaFieldProto::new("loadFactor", "F", Default::default()), + JavaFieldProto::new( + "table", + "[Ljava/util/Hashtable$Entry;", + FieldAccessFlags::PRIVATE | FieldAccessFlags::TRANSIENT, + ), + JavaFieldProto::new("count", "I", FieldAccessFlags::PRIVATE | FieldAccessFlags::TRANSIENT), + JavaFieldProto::new("threshold", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("loadFactor", "F", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/src/classes/java/util/hashtable_entry.rs b/java_runtime/src/classes/java/util/hashtable_entry.rs index 9588f6a7..e4593053 100644 --- a/java_runtime/src/classes/java/util/hashtable_entry.rs +++ b/java_runtime/src/classes/java/util/hashtable_entry.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -20,21 +20,26 @@ impl HashtableEntry { "", "(ILjava/lang/Object;Ljava/lang/Object;Ljava/util/Hashtable$Entry;)V", Self::init, - Default::default(), + MethodAccessFlags::PROTECTED, + ), + JavaMethodProto::new("getKey", "()Ljava/lang/Object;", Self::get_key, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getValue", "()Ljava/lang/Object;", Self::get_value, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + Self::set_value, + MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("getKey", "()Ljava/lang/Object;", Self::get_key, Default::default()), - JavaMethodProto::new("getValue", "()Ljava/lang/Object;", Self::get_value, Default::default()), - JavaMethodProto::new("setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", Self::set_value, Default::default()), JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("hash", "I", Default::default()), - JavaFieldProto::new("key", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("value", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("next", "Ljava/util/Hashtable$Entry;", Default::default()), + JavaFieldProto::new("hash", "I", FieldAccessFlags::FINAL), + JavaFieldProto::new("key", "Ljava/lang/Object;", FieldAccessFlags::FINAL), + JavaFieldProto::new("value", "Ljava/lang/Object;", FieldAccessFlags::empty()), + JavaFieldProto::new("next", "Ljava/util/Hashtable$Entry;", FieldAccessFlags::empty()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/hashtable_entry_set.rs b/java_runtime/src/classes/java/util/hashtable_entry_set.rs index 9dc76fbf..68a7f3da 100644 --- a/java_runtime/src/classes/java/util/hashtable_entry_set.rs +++ b/java_runtime/src/classes/java/util/hashtable_entry_set.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -18,16 +18,16 @@ impl HashtableEntrySet { parent_class: Some("java/util/AbstractSet"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Hashtable;)V", Self::init, Default::default()), - JavaMethodProto::new("size", "()I", Self::size, Default::default()), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Hashtable;)V", Self::init, MethodAccessFlags::PRIVATE), + JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, Default::default()), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("map", "Ljava/util/Hashtable;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("map", "Ljava/util/Hashtable;", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/hashtable_enumerator.rs b/java_runtime/src/classes/java/util/hashtable_enumerator.rs index c2c452b7..ea950f27 100644 --- a/java_runtime/src/classes/java/util/hashtable_enumerator.rs +++ b/java_runtime/src/classes/java/util/hashtable_enumerator.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -15,18 +16,18 @@ impl HashtableEnumerator { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Enumeration", "java/util/Iterator"], methods: vec![ - JavaMethodProto::new("", "([Ljava/lang/Object;)V", Self::init, Default::default()), - JavaMethodProto::new("hasMoreElements", "()Z", Self::has_more_elements, Default::default()), - JavaMethodProto::new("nextElement", "()Ljava/lang/Object;", Self::next_element, Default::default()), - JavaMethodProto::new("hasNext", "()Z", Self::has_next, Default::default()), - JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, Default::default()), - JavaMethodProto::new("remove", "()V", Self::remove, Default::default()), + JavaMethodProto::new("", "([Ljava/lang/Object;)V", Self::init, MethodAccessFlags::empty()), + JavaMethodProto::new("hasMoreElements", "()Z", Self::has_more_elements, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("nextElement", "()Ljava/lang/Object;", Self::next_element, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("remove", "()V", Self::remove, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("elements", "[Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("index", "I", Default::default()), + JavaFieldProto::new("elements", "[Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("index", "I", FieldAccessFlags::empty()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/hashtable_key_set.rs b/java_runtime/src/classes/java/util/hashtable_key_set.rs index b76a0564..929bd9b6 100644 --- a/java_runtime/src/classes/java/util/hashtable_key_set.rs +++ b/java_runtime/src/classes/java/util/hashtable_key_set.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -17,16 +18,16 @@ impl HashtableKeySet { parent_class: Some("java/util/AbstractSet"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Hashtable;)V", Self::init, Default::default()), - JavaMethodProto::new("size", "()I", Self::size, Default::default()), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), - JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, Default::default()), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Hashtable;)V", Self::init, MethodAccessFlags::PRIVATE), + JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("map", "Ljava/util/Hashtable;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("map", "Ljava/util/Hashtable;", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/hashtable_values.rs b/java_runtime/src/classes/java/util/hashtable_values.rs index 847a4252..cd9a27ae 100644 --- a/java_runtime/src/classes/java/util/hashtable_values.rs +++ b/java_runtime/src/classes/java/util/hashtable_values.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -18,16 +18,16 @@ impl HashtableValues { parent_class: Some("java/util/AbstractCollection"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Hashtable;)V", Self::init, Default::default()), - JavaMethodProto::new("size", "()I", Self::size, Default::default()), - JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, Default::default()), - JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Hashtable;)V", Self::init, MethodAccessFlags::empty()), + JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("isEmpty", "()Z", Self::is_empty, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("clear", "()V", Self::clear, Default::default()), - JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, Default::default()), + JavaMethodProto::new("clear", "()V", Self::clear, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("map", "Ljava/util/Hashtable;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("map", "Ljava/util/Hashtable;", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/illegal_format_exception.rs b/java_runtime/src/classes/java/util/illegal_format_exception.rs index f4cc4d54..f9b271ad 100644 --- a/java_runtime/src/classes/java/util/illegal_format_exception.rs +++ b/java_runtime/src/classes/java/util/illegal_format_exception.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::ClassAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext}; @@ -15,7 +15,7 @@ impl IllegalFormatException { name: "java/util/IllegalFormatException", parent_class: Some("java/lang/IllegalArgumentException"), interfaces: vec![], - methods: vec![JavaMethodProto::new("", "()V", Self::init, Default::default())], + methods: vec![JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::empty())], fields: vec![], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/src/classes/java/util/jar/attributes.rs b/java_runtime/src/classes/java/util/jar/attributes.rs index 081177f6..91bdfbba 100644 --- a/java_runtime/src/classes/java/util/jar/attributes.rs +++ b/java_runtime/src/classes/java/util/jar/attributes.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,17 +16,22 @@ impl Attributes { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Cloneable"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "putValue", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", Self::put_value, - Default::default(), + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new( + "getValue", + "(Ljava/lang/String;)Ljava/lang/String;", + Self::get_value, + MethodAccessFlags::PUBLIC, ), - JavaMethodProto::new("getValue", "(Ljava/lang/String;)Ljava/lang/String;", Self::get_value, Default::default()), ], - fields: vec![JavaFieldProto::new("map", "Ljava/util/Map;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("map", "Ljava/util/Map;", FieldAccessFlags::PROTECTED)], + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/util/jar/jar_entry.rs b/java_runtime/src/classes/java/util/jar/jar_entry.rs index a4f79990..0ed2eddf 100644 --- a/java_runtime/src/classes/java/util/jar/jar_entry.rs +++ b/java_runtime/src/classes/java/util/jar/jar_entry.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::util::zip::ZipEntry}; @@ -18,10 +19,10 @@ impl JarEntry { "", "(Ljava/util/zip/ZipEntry;)V", Self::init, - Default::default(), + MethodAccessFlags::PUBLIC, )], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/util/jar/jar_file_entries.rs b/java_runtime/src/classes/java/util/jar/jar_file_entries.rs index 9da235dc..000d6684 100644 --- a/java_runtime/src/classes/java/util/jar/jar_file_entries.rs +++ b/java_runtime/src/classes/java/util/jar/jar_file_entries.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -21,12 +22,16 @@ impl JarFileEntries { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Enumeration"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/zip/ZipFile$Entries;)V", Self::init, Default::default()), - JavaMethodProto::new("hasMoreElements", "()Z", Self::has_more_elements, Default::default()), - JavaMethodProto::new("nextElement", "()Ljava/lang/Object;", Self::next_element, Default::default()), + JavaMethodProto::new("", "(Ljava/util/zip/ZipFile$Entries;)V", Self::init, MethodAccessFlags::empty()), + JavaMethodProto::new("hasMoreElements", "()Z", Self::has_more_elements, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("nextElement", "()Ljava/lang/Object;", Self::next_element, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("entries", "Ljava/util/zip/ZipFile$Entries;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new( + "entries", + "Ljava/util/zip/ZipFile$Entries;", + FieldAccessFlags::PRIVATE, + )], + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/jar/manifest.rs b/java_runtime/src/classes/java/util/jar/manifest.rs index cea35b2d..c937f870 100644 --- a/java_runtime/src/classes/java/util/jar/manifest.rs +++ b/java_runtime/src/classes/java/util/jar/manifest.rs @@ -1,7 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -28,7 +28,7 @@ impl Manifest { MethodAccessFlags::PUBLIC, ), ], - fields: vec![JavaFieldProto::new("attrs", "Ljava/util/jar/Attributes;", Default::default())], + fields: vec![JavaFieldProto::new("attrs", "Ljava/util/jar/Attributes;", FieldAccessFlags::PRIVATE)], access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/util/linked_hash_map.rs b/java_runtime/src/classes/java/util/linked_hash_map.rs index feb7d0d6..6716ee7d 100644 --- a/java_runtime/src/classes/java/util/linked_hash_map.rs +++ b/java_runtime/src/classes/java/util/linked_hash_map.rs @@ -40,22 +40,32 @@ impl LinkedHashMap { Self::remove_eldest_entry, MethodAccessFlags::PROTECTED, ), - JavaMethodProto::new("initializeMap", "()V", Self::initialize_map, Default::default()), + JavaMethodProto::new("initializeMap", "()V", Self::initialize_map, MethodAccessFlags::empty()), JavaMethodProto::new( "storeNewEntry", "(ILjava/lang/Object;Ljava/lang/Object;I)V", Self::store_new_entry, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new( "insertNewEntry", "(ILjava/lang/Object;Ljava/lang/Object;I)V", Self::insert_new_entry, - Default::default(), + MethodAccessFlags::empty(), + ), + JavaMethodProto::new("keyIterator", "()Ljava/util/Iterator;", Self::key_iterator, MethodAccessFlags::empty()), + JavaMethodProto::new( + "valueIterator", + "()Ljava/util/Iterator;", + Self::value_iterator, + MethodAccessFlags::empty(), + ), + JavaMethodProto::new( + "entryIterator", + "()Ljava/util/Iterator;", + Self::entry_iterator, + MethodAccessFlags::empty(), ), - JavaMethodProto::new("keyIterator", "()Ljava/util/Iterator;", Self::key_iterator, Default::default()), - JavaMethodProto::new("valueIterator", "()Ljava/util/Iterator;", Self::value_iterator, Default::default()), - JavaMethodProto::new("entryIterator", "()Ljava/util/Iterator;", Self::entry_iterator, Default::default()), ], fields: vec![ JavaFieldProto::new( diff --git a/java_runtime/src/classes/java/util/linked_hash_map_entry.rs b/java_runtime/src/classes/java/util/linked_hash_map_entry.rs index e249c35c..1f1c5cc1 100644 --- a/java_runtime/src/classes/java/util/linked_hash_map_entry.rs +++ b/java_runtime/src/classes/java/util/linked_hash_map_entry.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -21,16 +22,16 @@ impl LinkedHashMapEntry { "", "(ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Entry;)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), ), - JavaMethodProto::new("onAccess", "(Ljava/util/HashMap;)V", Self::on_access, Default::default()), - JavaMethodProto::new("onRemoval", "(Ljava/util/HashMap;)V", Self::on_removal, Default::default()), + JavaMethodProto::new("onAccess", "(Ljava/util/HashMap;)V", Self::on_access, MethodAccessFlags::empty()), + JavaMethodProto::new("onRemoval", "(Ljava/util/HashMap;)V", Self::on_removal, MethodAccessFlags::empty()), ], fields: vec![ - JavaFieldProto::new("before", "Ljava/util/LinkedHashMap$Entry;", Default::default()), - JavaFieldProto::new("after", "Ljava/util/LinkedHashMap$Entry;", Default::default()), + JavaFieldProto::new("before", "Ljava/util/LinkedHashMap$Entry;", FieldAccessFlags::empty()), + JavaFieldProto::new("after", "Ljava/util/LinkedHashMap$Entry;", FieldAccessFlags::empty()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/linked_hash_map_entry_iterator.rs b/java_runtime/src/classes/java/util/linked_hash_map_entry_iterator.rs index 5367b4df..d24834f1 100644 --- a/java_runtime/src/classes/java/util/linked_hash_map_entry_iterator.rs +++ b/java_runtime/src/classes/java/util/linked_hash_map_entry_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -18,11 +18,11 @@ impl LinkedHashMapEntryIterator { parent_class: Some("java/util/LinkedHashMap$LinkedHashIterator"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/LinkedHashMap;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/LinkedHashMap;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/linked_hash_map_key_iterator.rs b/java_runtime/src/classes/java/util/linked_hash_map_key_iterator.rs index bad0e5be..38bda00d 100644 --- a/java_runtime/src/classes/java/util/linked_hash_map_key_iterator.rs +++ b/java_runtime/src/classes/java/util/linked_hash_map_key_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -18,11 +18,11 @@ impl LinkedHashMapKeyIterator { parent_class: Some("java/util/LinkedHashMap$LinkedHashIterator"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/LinkedHashMap;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/LinkedHashMap;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/linked_hash_map_linked_hash_iterator.rs b/java_runtime/src/classes/java/util/linked_hash_map_linked_hash_iterator.rs index 8ea97c33..5868604d 100644 --- a/java_runtime/src/classes/java/util/linked_hash_map_linked_hash_iterator.rs +++ b/java_runtime/src/classes/java/util/linked_hash_map_linked_hash_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -18,16 +18,21 @@ impl LinkedHashMapLinkedHashIterator { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Iterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/LinkedHashMap;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/LinkedHashMap;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "()V", Self::remove, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("nextEntry", "()Ljava/util/LinkedHashMap$Entry;", Self::next_entry, Default::default()), + JavaMethodProto::new( + "nextEntry", + "()Ljava/util/LinkedHashMap$Entry;", + Self::next_entry, + MethodAccessFlags::empty(), + ), ], fields: vec![ - JavaFieldProto::new("map", "Ljava/util/LinkedHashMap;", Default::default()), - JavaFieldProto::new("nextEntry", "Ljava/util/LinkedHashMap$Entry;", Default::default()), - JavaFieldProto::new("lastReturned", "Ljava/util/LinkedHashMap$Entry;", Default::default()), - JavaFieldProto::new("expectedModCount", "I", Default::default()), + JavaFieldProto::new("map", "Ljava/util/LinkedHashMap;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("nextEntry", "Ljava/util/LinkedHashMap$Entry;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("lastReturned", "Ljava/util/LinkedHashMap$Entry;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("expectedModCount", "I", FieldAccessFlags::empty()), ], access_flags: ClassAccessFlags::ABSTRACT, } diff --git a/java_runtime/src/classes/java/util/linked_hash_map_value_iterator.rs b/java_runtime/src/classes/java/util/linked_hash_map_value_iterator.rs index cd8cc76b..eb281ac6 100644 --- a/java_runtime/src/classes/java/util/linked_hash_map_value_iterator.rs +++ b/java_runtime/src/classes/java/util/linked_hash_map_value_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -18,11 +18,11 @@ impl LinkedHashMapValueIterator { parent_class: Some("java/util/LinkedHashMap$LinkedHashIterator"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/LinkedHashMap;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/LinkedHashMap;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/linked_list_entry.rs b/java_runtime/src/classes/java/util/linked_list_entry.rs index a45cebeb..d86016e5 100644 --- a/java_runtime/src/classes/java/util/linked_list_entry.rs +++ b/java_runtime/src/classes/java/util/linked_list_entry.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -18,14 +19,14 @@ impl LinkedListEntry { "", "(Ljava/lang/Object;Ljava/util/LinkedList$Entry;Ljava/util/LinkedList$Entry;)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), )], fields: vec![ - JavaFieldProto::new("element", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("next", "Ljava/util/LinkedList$Entry;", Default::default()), - JavaFieldProto::new("previous", "Ljava/util/LinkedList$Entry;", Default::default()), + JavaFieldProto::new("element", "Ljava/lang/Object;", FieldAccessFlags::empty()), + JavaFieldProto::new("next", "Ljava/util/LinkedList$Entry;", FieldAccessFlags::empty()), + JavaFieldProto::new("previous", "Ljava/util/LinkedList$Entry;", FieldAccessFlags::empty()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/linked_list_itr.rs b/java_runtime/src/classes/java/util/linked_list_itr.rs index 27cdaecf..992fdcd0 100644 --- a/java_runtime/src/classes/java/util/linked_list_itr.rs +++ b/java_runtime/src/classes/java/util/linked_list_itr.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl LinkedListItr { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/ListIterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/LinkedList;I)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/LinkedList;I)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("hasPrevious", "()Z", Self::has_previous, MethodAccessFlags::PUBLIC), @@ -28,11 +28,11 @@ impl LinkedListItr { JavaMethodProto::new("add", "(Ljava/lang/Object;)V", Self::add, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("list", "Ljava/util/LinkedList;", Default::default()), - JavaFieldProto::new("cursor", "I", Default::default()), - JavaFieldProto::new("lastReturned", "I", Default::default()), + JavaFieldProto::new("list", "Ljava/util/LinkedList;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("cursor", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("lastReturned", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/locale.rs b/java_runtime/src/classes/java/util/locale.rs index abd9ef8a..770f602d 100644 --- a/java_runtime/src/classes/java/util/locale.rs +++ b/java_runtime/src/classes/java/util/locale.rs @@ -22,18 +22,18 @@ impl Locale { interfaces: vec!["java/lang/Cloneable", "java/io/Serializable"], methods: vec![ JavaMethodProto::new("", "()V", Self::clinit, MethodAccessFlags::STATIC), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_language, Default::default()), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_language, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "", "(Ljava/lang/String;Ljava/lang/String;)V", Self::init_with_language_country, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", Self::init, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new("getDefault", "()Ljava/util/Locale;", Self::get_default, MethodAccessFlags::STATIC), JavaMethodProto::new("setDefault", "(Ljava/util/Locale;)V", Self::set_default, MethodAccessFlags::STATIC), @@ -55,63 +55,78 @@ impl Locale { Self::get_iso_languages, MethodAccessFlags::STATIC, ), - JavaMethodProto::new("getLanguage", "()Ljava/lang/String;", Self::get_language, Default::default()), - JavaMethodProto::new("getCountry", "()Ljava/lang/String;", Self::get_country, Default::default()), - JavaMethodProto::new("getVariant", "()Ljava/lang/String;", Self::get_variant, Default::default()), - JavaMethodProto::new("getISO3Language", "()Ljava/lang/String;", Self::get_iso3_language, Default::default()), - JavaMethodProto::new("getISO3Country", "()Ljava/lang/String;", Self::get_iso3_country, Default::default()), + JavaMethodProto::new("getLanguage", "()Ljava/lang/String;", Self::get_language, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getCountry", "()Ljava/lang/String;", Self::get_country, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getVariant", "()Ljava/lang/String;", Self::get_variant, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "getISO3Language", + "()Ljava/lang/String;", + Self::get_iso3_language, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new( + "getISO3Country", + "()Ljava/lang/String;", + Self::get_iso3_country, + MethodAccessFlags::PUBLIC, + ), JavaMethodProto::new( "getDisplayLanguage", "()Ljava/lang/String;", Self::get_display_language_default, - Default::default(), + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, ), JavaMethodProto::new( "getDisplayLanguage", "(Ljava/util/Locale;)Ljava/lang/String;", Self::get_display_language, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "getDisplayCountry", "()Ljava/lang/String;", Self::get_display_country_default, - Default::default(), + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, ), JavaMethodProto::new( "getDisplayCountry", "(Ljava/util/Locale;)Ljava/lang/String;", Self::get_display_country, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "getDisplayVariant", "()Ljava/lang/String;", Self::get_display_variant_default, - Default::default(), + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, ), JavaMethodProto::new( "getDisplayVariant", "(Ljava/util/Locale;)Ljava/lang/String;", Self::get_display_variant, - Default::default(), + MethodAccessFlags::PUBLIC, ), JavaMethodProto::new( "getDisplayName", "()Ljava/lang/String;", Self::get_display_name_default, - Default::default(), + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, ), JavaMethodProto::new( "getDisplayName", "(Ljava/util/Locale;)Ljava/lang/String;", Self::get_display_name, - Default::default(), + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("clone", "()Ljava/lang/Object;", Self::clone, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "toString", + "()Ljava/lang/String;", + Self::to_string, + MethodAccessFlags::PUBLIC | MethodAccessFlags::FINAL, ), - JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, Default::default()), - JavaMethodProto::new("hashCode", "()I", Self::hash_code, Default::default()), - JavaMethodProto::new("clone", "()Ljava/lang/Object;", Self::clone, Default::default()), - JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, Default::default()), ], fields: vec![ JavaFieldProto::new( diff --git a/java_runtime/src/classes/java/util/no_such_element_exception.rs b/java_runtime/src/classes/java/util/no_such_element_exception.rs index a95231bd..78ca4d59 100644 --- a/java_runtime/src/classes/java/util/no_such_element_exception.rs +++ b/java_runtime/src/classes/java/util/no_such_element_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl NoSuchElementException { parent_class: Some("java/lang/RuntimeException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/util/timer_task.rs b/java_runtime/src/classes/java/util/timer_task.rs index 7ce55bea..45fc3659 100644 --- a/java_runtime/src/classes/java/util/timer_task.rs +++ b/java_runtime/src/classes/java/util/timer_task.rs @@ -28,10 +28,10 @@ impl TimerTask { ], fields: vec![ JavaFieldProto::new("lock", "Ljava/lang/Object;", FieldAccessFlags::FINAL), - JavaFieldProto::new("state", "I", Default::default()), - JavaFieldProto::new("nextExecutionTime", "J", Default::default()), - JavaFieldProto::new("period", "J", Default::default()), - JavaFieldProto::new("lastScheduledExecutionTime", "J", Default::default()), + JavaFieldProto::new("state", "I", FieldAccessFlags::empty()), + JavaFieldProto::new("nextExecutionTime", "J", FieldAccessFlags::empty()), + JavaFieldProto::new("period", "J", FieldAccessFlags::empty()), + JavaFieldProto::new("lastScheduledExecutionTime", "J", FieldAccessFlags::empty()), ], access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::ABSTRACT, } diff --git a/java_runtime/src/classes/java/util/timer_task_queue.rs b/java_runtime/src/classes/java/util/timer_task_queue.rs index 1eefbf41..1e7520a5 100644 --- a/java_runtime/src/classes/java/util/timer_task_queue.rs +++ b/java_runtime/src/classes/java/util/timer_task_queue.rs @@ -1,7 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::FieldAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::util::TimerTask}; @@ -15,12 +15,12 @@ impl TimerTaskQueue { name: "java/util/Timer$TaskQueue", parent_class: Some("java/lang/Object"), interfaces: vec![], - methods: vec![JavaMethodProto::new("", "()V", Self::init, Default::default())], + methods: vec![JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::empty())], fields: vec![ JavaFieldProto::new("queue", "[Ljava/util/TimerTask;", FieldAccessFlags::PRIVATE), JavaFieldProto::new("size", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/timer_thread.rs b/java_runtime/src/classes/java/util/timer_thread.rs index b75e5d4a..3df816cb 100644 --- a/java_runtime/src/classes/java/util/timer_thread.rs +++ b/java_runtime/src/classes/java/util/timer_thread.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, JavaError, Jvm, Result}; use crate::{ @@ -25,14 +25,14 @@ impl TimerThread { parent_class: Some("java/lang/Thread"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Timer$TaskQueue;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Timer$TaskQueue;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("run", "()V", Self::run, MethodAccessFlags::PUBLIC), ], fields: vec![ JavaFieldProto::new("queue", "Ljava/util/Timer$TaskQueue;", FieldAccessFlags::PRIVATE), - JavaFieldProto::new("newTasksMayBeScheduled", "Z", Default::default()), + JavaFieldProto::new("newTasksMayBeScheduled", "Z", FieldAccessFlags::empty()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/tree_map.rs b/java_runtime/src/classes/java/util/tree_map.rs index 790014a4..154d7a44 100644 --- a/java_runtime/src/classes/java/util/tree_map.rs +++ b/java_runtime/src/classes/java/util/tree_map.rs @@ -64,9 +64,19 @@ impl TreeMap { JavaMethodProto::new("keySet", "()Ljava/util/Set;", Self::key_set, MethodAccessFlags::PUBLIC), JavaMethodProto::new("values", "()Ljava/util/Collection;", Self::values, MethodAccessFlags::PUBLIC), JavaMethodProto::new("entrySet", "()Ljava/util/Set;", Self::entry_set, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("keyIterator", "()Ljava/util/Iterator;", Self::key_iterator, Default::default()), - JavaMethodProto::new("valueIterator", "()Ljava/util/Iterator;", Self::value_iterator, Default::default()), - JavaMethodProto::new("entryIterator", "()Ljava/util/Iterator;", Self::entry_iterator, Default::default()), + JavaMethodProto::new("keyIterator", "()Ljava/util/Iterator;", Self::key_iterator, MethodAccessFlags::empty()), + JavaMethodProto::new( + "valueIterator", + "()Ljava/util/Iterator;", + Self::value_iterator, + MethodAccessFlags::empty(), + ), + JavaMethodProto::new( + "entryIterator", + "()Ljava/util/Iterator;", + Self::entry_iterator, + MethodAccessFlags::empty(), + ), ], fields: vec![ JavaFieldProto::new( diff --git a/java_runtime/src/classes/java/util/tree_map_entry.rs b/java_runtime/src/classes/java/util/tree_map_entry.rs index 629125b4..1b533f12 100644 --- a/java_runtime/src/classes/java/util/tree_map_entry.rs +++ b/java_runtime/src/classes/java/util/tree_map_entry.rs @@ -20,7 +20,7 @@ impl TreeMapEntry { "", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/util/TreeMap$Entry;)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new("getKey", "()Ljava/lang/Object;", Self::get_key, MethodAccessFlags::PUBLIC), JavaMethodProto::new("getValue", "()Ljava/lang/Object;", Self::get_value, MethodAccessFlags::PUBLIC), diff --git a/java_runtime/src/classes/java/util/tree_map_entry_iterator.rs b/java_runtime/src/classes/java/util/tree_map_entry_iterator.rs index 74c3593b..7efde8d6 100644 --- a/java_runtime/src/classes/java/util/tree_map_entry_iterator.rs +++ b/java_runtime/src/classes/java/util/tree_map_entry_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -22,12 +22,12 @@ impl TreeMapEntryIterator { "", "(Ljava/util/TreeMap;Ljava/util/TreeMap$Entry;Ljava/lang/Object;Z)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/tree_map_entry_set.rs b/java_runtime/src/classes/java/util/tree_map_entry_set.rs index 7b00222b..dec1189a 100644 --- a/java_runtime/src/classes/java/util/tree_map_entry_set.rs +++ b/java_runtime/src/classes/java/util/tree_map_entry_set.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl TreeMapEntrySet { parent_class: Some("java/util/AbstractSet"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC), @@ -24,7 +24,7 @@ impl TreeMapEntrySet { JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("map", "Ljava/util/SortedMap;", FieldAccessFlags::PRIVATE)], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/tree_map_key_iterator.rs b/java_runtime/src/classes/java/util/tree_map_key_iterator.rs index 1cc6bfca..d6c25111 100644 --- a/java_runtime/src/classes/java/util/tree_map_key_iterator.rs +++ b/java_runtime/src/classes/java/util/tree_map_key_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -22,12 +22,12 @@ impl TreeMapKeyIterator { "", "(Ljava/util/TreeMap;Ljava/util/TreeMap$Entry;Ljava/lang/Object;Z)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/tree_map_key_set.rs b/java_runtime/src/classes/java/util/tree_map_key_set.rs index 06f80239..e61ab24e 100644 --- a/java_runtime/src/classes/java/util/tree_map_key_set.rs +++ b/java_runtime/src/classes/java/util/tree_map_key_set.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl TreeMapKeySet { parent_class: Some("java/util/AbstractSet"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC), @@ -24,7 +24,7 @@ impl TreeMapKeySet { JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("map", "Ljava/util/SortedMap;", FieldAccessFlags::PRIVATE)], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/tree_map_private_entry_iterator.rs b/java_runtime/src/classes/java/util/tree_map_private_entry_iterator.rs index d9cbd23d..68c91cd1 100644 --- a/java_runtime/src/classes/java/util/tree_map_private_entry_iterator.rs +++ b/java_runtime/src/classes/java/util/tree_map_private_entry_iterator.rs @@ -22,7 +22,7 @@ impl TreeMapPrivateEntryIterator { "", "(Ljava/util/TreeMap;Ljava/util/TreeMap$Entry;Ljava/lang/Object;Z)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), JavaMethodProto::new_abstract("next", "()Ljava/lang/Object;", MethodAccessFlags::PUBLIC | MethodAccessFlags::ABSTRACT), diff --git a/java_runtime/src/classes/java/util/tree_map_sub_map.rs b/java_runtime/src/classes/java/util/tree_map_sub_map.rs index 1feb81e7..cced84ed 100644 --- a/java_runtime/src/classes/java/util/tree_map_sub_map.rs +++ b/java_runtime/src/classes/java/util/tree_map_sub_map.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -22,7 +22,7 @@ impl TreeMapSubMap { "", "(Ljava/util/TreeMap;ZLjava/lang/Object;ZLjava/lang/Object;)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("containsKey", "(Ljava/lang/Object;)Z", Self::contains_key, MethodAccessFlags::PUBLIC), @@ -65,9 +65,19 @@ impl TreeMapSubMap { JavaMethodProto::new("keySet", "()Ljava/util/Set;", Self::key_set, MethodAccessFlags::PUBLIC), JavaMethodProto::new("values", "()Ljava/util/Collection;", Self::values, MethodAccessFlags::PUBLIC), JavaMethodProto::new("entrySet", "()Ljava/util/Set;", Self::entry_set, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("keyIterator", "()Ljava/util/Iterator;", Self::key_iterator, Default::default()), - JavaMethodProto::new("valueIterator", "()Ljava/util/Iterator;", Self::value_iterator, Default::default()), - JavaMethodProto::new("entryIterator", "()Ljava/util/Iterator;", Self::entry_iterator, Default::default()), + JavaMethodProto::new("keyIterator", "()Ljava/util/Iterator;", Self::key_iterator, MethodAccessFlags::empty()), + JavaMethodProto::new( + "valueIterator", + "()Ljava/util/Iterator;", + Self::value_iterator, + MethodAccessFlags::empty(), + ), + JavaMethodProto::new( + "entryIterator", + "()Ljava/util/Iterator;", + Self::entry_iterator, + MethodAccessFlags::empty(), + ), ], fields: vec![ JavaFieldProto::new("m", "Ljava/util/TreeMap;", FieldAccessFlags::PRIVATE), @@ -76,7 +86,7 @@ impl TreeMapSubMap { JavaFieldProto::new("toEnd", "Z", FieldAccessFlags::PRIVATE), JavaFieldProto::new("toKey", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/tree_map_value_iterator.rs b/java_runtime/src/classes/java/util/tree_map_value_iterator.rs index eb322687..b86e39a7 100644 --- a/java_runtime/src/classes/java/util/tree_map_value_iterator.rs +++ b/java_runtime/src/classes/java/util/tree_map_value_iterator.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -22,12 +22,12 @@ impl TreeMapValueIterator { "", "(Ljava/util/TreeMap;Ljava/util/TreeMap$Entry;Ljava/lang/Object;Z)V", Self::init, - Default::default(), + MethodAccessFlags::empty(), ), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/tree_map_values.rs b/java_runtime/src/classes/java/util/tree_map_values.rs index ee6a64bb..ba5b816f 100644 --- a/java_runtime/src/classes/java/util/tree_map_values.rs +++ b/java_runtime/src/classes/java/util/tree_map_values.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,7 +16,7 @@ impl TreeMapValues { parent_class: Some("java/util/AbstractCollection"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "(Ljava/lang/Object;)Z", Self::remove, MethodAccessFlags::PUBLIC), @@ -24,7 +24,7 @@ impl TreeMapValues { JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), ], fields: vec![JavaFieldProto::new("map", "Ljava/util/SortedMap;", FieldAccessFlags::PRIVATE)], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/java/util/tree_set.rs b/java_runtime/src/classes/java/util/tree_set.rs index 9061fd0f..4ebc22d8 100644 --- a/java_runtime/src/classes/java/util/tree_set.rs +++ b/java_runtime/src/classes/java/util/tree_set.rs @@ -21,7 +21,7 @@ impl TreeSet { JavaMethodProto::new("", "(Ljava/util/Comparator;)V", Self::init_comparator, MethodAccessFlags::PUBLIC), JavaMethodProto::new("", "(Ljava/util/Collection;)V", Self::init_collection, MethodAccessFlags::PUBLIC), JavaMethodProto::new("", "(Ljava/util/SortedSet;)V", Self::init_sorted_set, MethodAccessFlags::PUBLIC), - JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init_sorted_map, Default::default()), + JavaMethodProto::new("", "(Ljava/util/SortedMap;)V", Self::init_sorted_map, MethodAccessFlags::PRIVATE), JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), JavaMethodProto::new("add", "(Ljava/lang/Object;)Z", Self::add, MethodAccessFlags::PUBLIC), diff --git a/java_runtime/src/classes/java/util/vector_itr.rs b/java_runtime/src/classes/java/util/vector_itr.rs index cd42fb34..358d9663 100644 --- a/java_runtime/src/classes/java/util/vector_itr.rs +++ b/java_runtime/src/classes/java/util/vector_itr.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object}; @@ -16,17 +16,17 @@ impl VectorItr { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Iterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Vector;I)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Vector;I)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasNext", "()Z", Self::has_next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("next", "()Ljava/lang/Object;", Self::next, MethodAccessFlags::PUBLIC), JavaMethodProto::new("remove", "()V", Self::remove, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("list", "Ljava/util/Vector;", Default::default()), - JavaFieldProto::new("cursor", "I", Default::default()), - JavaFieldProto::new("lastReturned", "I", Default::default()), + JavaFieldProto::new("list", "Ljava/util/Vector;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("cursor", "I", FieldAccessFlags::empty()), + JavaFieldProto::new("lastReturned", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -36,7 +36,7 @@ impl VectorItr { parent_class: Some("java/util/Vector$Itr"), interfaces: vec!["java/util/ListIterator"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/Vector;I)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/util/Vector;I)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("hasPrevious", "()Z", Self::has_previous, MethodAccessFlags::PUBLIC), JavaMethodProto::new("previous", "()Ljava/lang/Object;", Self::previous, MethodAccessFlags::PUBLIC), JavaMethodProto::new("nextIndex", "()I", Self::next_index, MethodAccessFlags::PUBLIC), @@ -45,7 +45,7 @@ impl VectorItr { JavaMethodProto::new("add", "(Ljava/lang/Object;)V", Self::add, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::FINAL, } } diff --git a/java_runtime/src/classes/java/util/zip/zip_entry.rs b/java_runtime/src/classes/java/util/zip/zip_entry.rs index 46a40ea9..28bfb074 100644 --- a/java_runtime/src/classes/java/util/zip/zip_entry.rs +++ b/java_runtime/src/classes/java/util/zip/zip_entry.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,17 +16,22 @@ impl ZipEntry { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Cloneable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/util/zip/ZipEntry;)V", Self::init_with_zip_entry, Default::default()), - JavaMethodProto::new("getName", "()Ljava/lang/String;", Self::get_name, Default::default()), - JavaMethodProto::new("setSize", "(J)V", Self::set_size, Default::default()), - JavaMethodProto::new("getSize", "()J", Self::get_size, Default::default()), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "", + "(Ljava/util/zip/ZipEntry;)V", + Self::init_with_zip_entry, + MethodAccessFlags::PUBLIC, + ), + JavaMethodProto::new("getName", "()Ljava/lang/String;", Self::get_name, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("setSize", "(J)V", Self::set_size, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getSize", "()J", Self::get_size, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("name", "Ljava/lang/String;", Default::default()), - JavaFieldProto::new("size", "J", Default::default()), + JavaFieldProto::new("name", "Ljava/lang/String;", FieldAccessFlags::empty()), + JavaFieldProto::new("size", "J", FieldAccessFlags::empty()), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/util/zip/zip_exception.rs b/java_runtime/src/classes/java/util/zip/zip_exception.rs index fffde9f5..a1dbb3fd 100644 --- a/java_runtime/src/classes/java/util/zip/zip_exception.rs +++ b/java_runtime/src/classes/java/util/zip/zip_exception.rs @@ -1,6 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{RuntimeClassProto, RuntimeContext, classes::java::lang::String}; @@ -15,11 +16,11 @@ impl ZipException { parent_class: Some("java/io/IOException"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("", "(Ljava/lang/String;)V", Self::init_with_message, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/util/zip/zip_file.rs b/java_runtime/src/classes/java/util/zip/zip_file.rs index 0257d547..cecfa862 100644 --- a/java_runtime/src/classes/java/util/zip/zip_file.rs +++ b/java_runtime/src/classes/java/util/zip/zip_file.rs @@ -8,7 +8,7 @@ use std::io::{Cursor, Read}; use zip::ZipArchive; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -45,7 +45,7 @@ impl ZipFile { ), JavaMethodProto::new("entries", "()Ljava/util/Enumeration;", Self::entries, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("zipData", "[B", Default::default())], + fields: vec![JavaFieldProto::new("zipData", "[B", FieldAccessFlags::PRIVATE)], access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/java/util/zip/zip_file_entries.rs b/java_runtime/src/classes/java/util/zip/zip_file_entries.rs index 03379872..cfefdc06 100644 --- a/java_runtime/src/classes/java/util/zip/zip_file_entries.rs +++ b/java_runtime/src/classes/java/util/zip/zip_file_entries.rs @@ -1,6 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result}; use crate::{ @@ -21,16 +22,21 @@ impl ZipFileEntries { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Enumeration"], methods: vec![ - JavaMethodProto::new("", "(Ljava/util/zip/ZipFile;[Ljava/lang/String;)V", Self::init, Default::default()), - JavaMethodProto::new("hasMoreElements", "()Z", Self::has_more_elements, Default::default()), - JavaMethodProto::new("nextElement", "()Ljava/lang/Object;", Self::next_element, Default::default()), + JavaMethodProto::new( + "", + "(Ljava/util/zip/ZipFile;[Ljava/lang/String;)V", + Self::init, + MethodAccessFlags::empty(), + ), + JavaMethodProto::new("hasMoreElements", "()Z", Self::has_more_elements, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("nextElement", "()Ljava/lang/Object;", Self::next_element, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("zipFile", "Ljava/util/zip/ZipFile;", Default::default()), - JavaFieldProto::new("names", "[Ljava/lang/String;", Default::default()), - JavaFieldProto::new("i", "I", Default::default()), + JavaFieldProto::new("zipFile", "Ljava/util/zip/ZipFile;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("names", "[Ljava/lang/String;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("i", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/org/rustjava/lang/rust_jar_class_loader.rs b/java_runtime/src/classes/org/rustjava/lang/rust_jar_class_loader.rs index 24af72e5..005f4160 100644 --- a/java_runtime/src/classes/org/rustjava/lang/rust_jar_class_loader.rs +++ b/java_runtime/src/classes/org/rustjava/lang/rust_jar_class_loader.rs @@ -1,7 +1,7 @@ use alloc::{vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{Array, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -32,8 +32,8 @@ impl RustJarClassLoader { MethodAccessFlags::PROTECTED, ), ], - fields: vec![JavaFieldProto::new("classPaths", "[Ljava/lang/String;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("classPaths", "[Ljava/lang/String;", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::PUBLIC, } } diff --git a/java_runtime/src/classes/org/rustjava/net/file_url_connection.rs b/java_runtime/src/classes/org/rustjava/net/file_url_connection.rs index 7e205c79..4ad92d28 100644 --- a/java_runtime/src/classes/org/rustjava/net/file_url_connection.rs +++ b/java_runtime/src/classes/org/rustjava/net/file_url_connection.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -22,7 +22,7 @@ impl FileURLConnection { parent_class: Some("java/net/URLConnection"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/net/URL;Ljava/io/File;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/net/URL;Ljava/io/File;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new( "getInputStream", "()Ljava/io/InputStream;", @@ -30,8 +30,8 @@ impl FileURLConnection { MethodAccessFlags::PUBLIC, ), ], - fields: vec![JavaFieldProto::new("file", "Ljava/io/File;", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("file", "Ljava/io/File;", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/org/rustjava/net/file_url_handler.rs b/java_runtime/src/classes/org/rustjava/net/file_url_handler.rs index 125125f1..90712e88 100644 --- a/java_runtime/src/classes/org/rustjava/net/file_url_handler.rs +++ b/java_runtime/src/classes/org/rustjava/net/file_url_handler.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -22,7 +22,7 @@ impl FileURLHandler { parent_class: Some("java/net/URLStreamHandler"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new( "openConnection", "(Ljava/net/URL;)Ljava/net/URLConnection;", @@ -31,7 +31,7 @@ impl FileURLHandler { ), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/org/rustjava/net/jar_url_connection.rs b/java_runtime/src/classes/org/rustjava/net/jar_url_connection.rs index 17d6faa8..75280717 100644 --- a/java_runtime/src/classes/org/rustjava/net/jar_url_connection.rs +++ b/java_runtime/src/classes/org/rustjava/net/jar_url_connection.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{FieldAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; use crate::{ @@ -25,7 +25,7 @@ impl JarURLConnection { interfaces: vec![], methods: vec![ JavaMethodProto::new("", "()V", Self::clinit, MethodAccessFlags::STATIC), - JavaMethodProto::new("", "(Ljava/net/URL;)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Ljava/net/URL;)V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new("getJarFile", "()Ljava/util/jar/JarFile;", Self::get_jar_file, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "getInputStream", @@ -35,7 +35,7 @@ impl JarURLConnection { ), ], fields: vec![JavaFieldProto::new("openedFiles", "Ljava/util/Hashtable;", FieldAccessFlags::STATIC)], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/src/classes/org/rustjava/net/jar_url_handler.rs b/java_runtime/src/classes/org/rustjava/net/jar_url_handler.rs index c2a29e5f..5d405199 100644 --- a/java_runtime/src/classes/org/rustjava/net/jar_url_handler.rs +++ b/java_runtime/src/classes/org/rustjava/net/jar_url_handler.rs @@ -1,7 +1,7 @@ use alloc::vec; use java_class_proto::JavaMethodProto; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, MethodAccessFlags}; use jvm::{ClassInstanceRef, Jvm, Result}; use crate::{ @@ -19,7 +19,7 @@ impl JarURLHandler { parent_class: Some("java/net/URLStreamHandler"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::empty()), JavaMethodProto::new( "openConnection", "(Ljava/net/URL;)Ljava/net/URLConnection;", @@ -28,7 +28,7 @@ impl JarURLHandler { ), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/tests/classes/java/io/test_buffered_reader.rs b/java_runtime/tests/classes/java/io/test_buffered_reader.rs index 927a81ba..01924cde 100644 --- a/java_runtime/tests/classes/java/io/test_buffered_reader.rs +++ b/java_runtime/tests/classes/java/io/test_buffered_reader.rs @@ -2,6 +2,7 @@ use alloc::{boxed::Box, collections::BTreeMap, vec, vec::Vec}; use core::time::Duration; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use java_runtime::{ RuntimeClassProto, RuntimeContext, classes::java::{ @@ -23,21 +24,21 @@ impl ChunkedReader { parent_class: Some("java/io/Reader"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "([CI)V", Self::init, Default::default()), - JavaMethodProto::new("read", "([CII)I", Self::read, Default::default()), - JavaMethodProto::new("ready", "()Z", Self::ready, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), + JavaMethodProto::new("", "([CI)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "([CII)I", Self::read, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("ready", "()Z", Self::ready, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("data", "[C", Default::default()), - JavaFieldProto::new("position", "I", Default::default()), - JavaFieldProto::new("chunkSize", "I", Default::default()), - JavaFieldProto::new("visibleLength", "I", Default::default()), - JavaFieldProto::new("zeroReads", "I", Default::default()), - JavaFieldProto::new("closed", "Z", Default::default()), - JavaFieldProto::new("closeCount", "I", Default::default()), + JavaFieldProto::new("data", "[C", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("position", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("chunkSize", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("visibleLength", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("zeroReads", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("closed", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("closeCount", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -131,16 +132,16 @@ impl ReadRunner { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Runnable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/BufferedReader;)V", Self::init, Default::default()), - JavaMethodProto::new("run", "()V", Self::run, Default::default()), + JavaMethodProto::new("", "(Ljava/io/BufferedReader;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("run", "()V", Self::run, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("reader", "Ljava/io/BufferedReader;", Default::default()), - JavaFieldProto::new("started", "Z", Default::default()), - JavaFieldProto::new("done", "Z", Default::default()), - JavaFieldProto::new("value", "I", Default::default()), + JavaFieldProto::new("reader", "Ljava/io/BufferedReader;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("started", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("done", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("value", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/tests/classes/java/io/test_input_stream_reader.rs b/java_runtime/tests/classes/java/io/test_input_stream_reader.rs index ea56ad46..cb4361a5 100644 --- a/java_runtime/tests/classes/java/io/test_input_stream_reader.rs +++ b/java_runtime/tests/classes/java/io/test_input_stream_reader.rs @@ -1,6 +1,7 @@ use alloc::{boxed::Box, collections::BTreeMap, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use java_runtime::classes::java::lang::Object; use java_runtime::{RuntimeClassProto, RuntimeContext}; use jvm::{Array, ClassInstanceRef, JavaChar, JavaError, Jvm, Result, runtime::JavaLangString}; @@ -17,15 +18,15 @@ impl OneByteInputStream { parent_class: Some("java/io/InputStream"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "([B)V", Self::init, Default::default()), - JavaMethodProto::new("read", "()I", Self::read, Default::default()), - JavaMethodProto::new("read", "([BII)I", Self::read_offset_length, Default::default()), + JavaMethodProto::new("", "([B)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "()I", Self::read, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("read", "([BII)I", Self::read_offset_length, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("data", "[B", Default::default()), - JavaFieldProto::new("position", "I", Default::default()), + JavaFieldProto::new("data", "[B", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("position", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/tests/classes/java/io/test_print_writer.rs b/java_runtime/tests/classes/java/io/test_print_writer.rs index bf6ff9ce..e0c2febf 100644 --- a/java_runtime/tests/classes/java/io/test_print_writer.rs +++ b/java_runtime/tests/classes/java/io/test_print_writer.rs @@ -24,27 +24,27 @@ impl ProbeWriter { parent_class: Some("java/io/Writer"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(III)V", Self::init, Default::default()), - JavaMethodProto::new("write", "([CII)V", Self::write, Default::default()), - JavaMethodProto::new("flush", "()V", Self::flush, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), + JavaMethodProto::new("", "(III)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("write", "([CII)V", Self::write, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("flush", "()V", Self::flush, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("content", "Ljava/lang/StringBuffer;", Default::default()), - JavaFieldProto::new("writeMode", "I", Default::default()), - JavaFieldProto::new("flushMode", "I", Default::default()), - JavaFieldProto::new("closeMode", "I", Default::default()), - JavaFieldProto::new("writeCount", "I", Default::default()), - JavaFieldProto::new("flushCount", "I", Default::default()), - JavaFieldProto::new("closeCount", "I", Default::default()), - JavaFieldProto::new("blockFirstWrite", "Z", Default::default()), - JavaFieldProto::new("firstWriteEntered", "Z", Default::default()), - JavaFieldProto::new("releaseFirstWrite", "Z", Default::default()), - JavaFieldProto::new("blockFirstClose", "Z", Default::default()), - JavaFieldProto::new("firstCloseEntered", "Z", Default::default()), - JavaFieldProto::new("releaseFirstClose", "Z", Default::default()), + JavaFieldProto::new("content", "Ljava/lang/StringBuffer;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("writeMode", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("flushMode", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("closeMode", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("writeCount", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("flushCount", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("closeCount", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("blockFirstWrite", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("firstWriteEntered", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("releaseFirstWrite", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("blockFirstClose", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("firstCloseEntered", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("releaseFirstClose", "Z", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -160,12 +160,12 @@ impl OverridePrintWriter { parent_class: Some("java/io/PrintWriter"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/Writer;)V", Self::init, Default::default()), - JavaMethodProto::new("print", "(I)V", Self::print_int, Default::default()), - JavaMethodProto::new("println", "()V", Self::println, Default::default()), + JavaMethodProto::new("", "(Ljava/io/Writer;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("print", "(I)V", Self::print_int, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("println", "()V", Self::println, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -196,16 +196,16 @@ impl PrintWriterRunner { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Runnable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/PrintWriter;I)V", Self::init, Default::default()), - JavaMethodProto::new("run", "()V", Self::run, Default::default()), + JavaMethodProto::new("", "(Ljava/io/PrintWriter;I)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("run", "()V", Self::run, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("writer", "Ljava/io/PrintWriter;", Default::default()), - JavaFieldProto::new("value", "I", Default::default()), - JavaFieldProto::new("started", "Z", Default::default()), - JavaFieldProto::new("done", "Z", Default::default()), + JavaFieldProto::new("writer", "Ljava/io/PrintWriter;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("value", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("started", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("done", "Z", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -241,15 +241,15 @@ impl PrintWriterCloseRunner { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Runnable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/io/PrintWriter;)V", Self::init, Default::default()), - JavaMethodProto::new("run", "()V", Self::run, Default::default()), + JavaMethodProto::new("", "(Ljava/io/PrintWriter;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("run", "()V", Self::run, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("writer", "Ljava/io/PrintWriter;", Default::default()), - JavaFieldProto::new("started", "Z", Default::default()), - JavaFieldProto::new("done", "Z", Default::default()), + JavaFieldProto::new("writer", "Ljava/io/PrintWriter;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("started", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("done", "Z", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/tests/classes/java/io/test_stream_locking.rs b/java_runtime/tests/classes/java/io/test_stream_locking.rs index 14c3cd4e..61c649d5 100644 --- a/java_runtime/tests/classes/java/io/test_stream_locking.rs +++ b/java_runtime/tests/classes/java/io/test_stream_locking.rs @@ -2,6 +2,7 @@ use alloc::{boxed::Box, collections::BTreeMap, vec}; use core::time::Duration; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use java_runtime::{ RuntimeClassProto, RuntimeContext, classes::java::{ @@ -22,20 +23,20 @@ impl LockCheckingWriter { parent_class: Some("java/io/Writer"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(IZ)V", Self::init, Default::default()), - JavaMethodProto::new("write", "([CII)V", Self::write, Default::default()), - JavaMethodProto::new("flush", "()V", Self::flush, Default::default()), - JavaMethodProto::new("close", "()V", Self::close, Default::default()), + JavaMethodProto::new("", "(IZ)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("write", "([CII)V", Self::write, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("flush", "()V", Self::flush, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("close", "()V", Self::close, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("failWrites", "I", Default::default()), - JavaFieldProto::new("failClose", "Z", Default::default()), - JavaFieldProto::new("writeCalls", "I", Default::default()), - JavaFieldProto::new("flushCalls", "I", Default::default()), - JavaFieldProto::new("closeCalls", "I", Default::default()), - JavaFieldProto::new("written", "I", Default::default()), + JavaFieldProto::new("failWrites", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("failClose", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("writeCalls", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("flushCalls", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("closeCalls", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("written", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -95,16 +96,16 @@ impl StreamOperationRunner { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Runnable"], methods: vec![ - JavaMethodProto::new("", "(Ljava/lang/Object;I)V", Self::init, Default::default()), - JavaMethodProto::new("run", "()V", Self::run, Default::default()), + JavaMethodProto::new("", "(Ljava/lang/Object;I)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("run", "()V", Self::run, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("target", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("operation", "I", Default::default()), - JavaFieldProto::new("started", "Z", Default::default()), - JavaFieldProto::new("done", "Z", Default::default()), + JavaFieldProto::new("target", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("operation", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("started", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("done", "Z", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/tests/classes/java/lang/test_class.rs b/java_runtime/tests/classes/java/lang/test_class.rs index fdd7d4d9..bb155ed2 100644 --- a/java_runtime/tests/classes/java/lang/test_class.rs +++ b/java_runtime/tests/classes/java/lang/test_class.rs @@ -500,7 +500,11 @@ async fn test_cldc_class_queries_and_new_instance() -> Result<()> { #[tokio::test] async fn test_base_class_loader_delegates_to_bootstrap_and_find_class_throws() -> Result<()> { let jvm = test_jvm().await?; - let loader = jvm.new_class("java/lang/ClassLoader", "(Ljava/lang/ClassLoader;)V", (None,)).await?; + let urls = jvm.instantiate_array("Ljava/net/URL;", 0).await?; + let loader: ClassInstanceRef = jvm + .new_class("java/net/URLClassLoader", "([Ljava/net/URL;Ljava/lang/ClassLoader;)V", (urls, None)) + .await? + .into(); let name = JavaLangString::from_rust_string(&jvm, "java/util/Random").await?; let class: ClassInstanceRef = jvm @@ -517,7 +521,7 @@ async fn test_base_class_loader_delegates_to_bootstrap_and_find_class_throws() - let name = JavaLangString::from_rust_string(&jvm, "missing.Type").await?; let result: Result> = jvm - .invoke_virtual( + .invoke_special( &loader, "java/lang/ClassLoader", "findClass", @@ -572,8 +576,9 @@ async fn test_system_class_loader_uses_rustjar_parent() -> Result<()> { #[tokio::test] async fn test_define_class_translates_parser_errors_to_java_errors() -> Result<()> { let jvm = test_jvm().await?; + let urls = jvm.instantiate_array("Ljava/net/URL;", 0).await?; let loader: ClassInstanceRef = jvm - .new_class("java/lang/ClassLoader", "(Ljava/lang/ClassLoader;)V", (None,)) + .new_class("java/net/URLClassLoader", "([Ljava/net/URL;Ljava/lang/ClassLoader;)V", (urls, None)) .await? .into(); let name: ClassInstanceRef = None.into(); @@ -620,8 +625,9 @@ async fn test_define_class_translates_parser_errors_to_java_errors() -> Result<( #[tokio::test] async fn test_define_class_validates_the_byte_range() -> Result<()> { let jvm = test_jvm().await?; + let urls = jvm.instantiate_array("Ljava/net/URL;", 0).await?; let loader: ClassInstanceRef = jvm - .new_class("java/lang/ClassLoader", "(Ljava/lang/ClassLoader;)V", (None,)) + .new_class("java/net/URLClassLoader", "([Ljava/net/URL;Ljava/lang/ClassLoader;)V", (urls, None)) .await? .into(); let name: ClassInstanceRef = None.into(); diff --git a/java_runtime/tests/classes/java/lang/test_object.rs b/java_runtime/tests/classes/java/lang/test_object.rs index 6b221641..2056d6da 100644 --- a/java_runtime/tests/classes/java/lang/test_object.rs +++ b/java_runtime/tests/classes/java/lang/test_object.rs @@ -7,6 +7,7 @@ use core::{ use alloc::{boxed::Box, collections::btree_map::BTreeMap, sync::Arc, vec}; use java_class_proto::JavaFieldProto; +use java_constants::{ClassAccessFlags, FieldAccessFlags}; use java_runtime::{Runtime, RuntimeClassProto, SpawnCallback, classes::java::lang::Object}; use jvm::{Array, ClassInstanceRef, JavaError, Jvm, Result}; use jvm_rust::ClassDefinitionImpl; @@ -23,10 +24,10 @@ impl CloneableObject { interfaces: vec!["java/lang/Cloneable"], methods: vec![], fields: vec![ - JavaFieldProto::new("value", "I", Default::default()), - JavaFieldProto::new("reference", "Ljava/lang/Object;", Default::default()), + JavaFieldProto::new("value", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("reference", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } } diff --git a/java_runtime/tests/classes/java/lang/test_thread.rs b/java_runtime/tests/classes/java/lang/test_thread.rs index f160157e..6755c893 100644 --- a/java_runtime/tests/classes/java/lang/test_thread.rs +++ b/java_runtime/tests/classes/java/lang/test_thread.rs @@ -1,7 +1,7 @@ use alloc::{boxed::Box, collections::BTreeMap, vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::MethodAccessFlags; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use java_runtime::{RuntimeClassProto, RuntimeContext}; use jvm::{ClassInstanceRef, JavaError, Jvm, Result, runtime::JavaLangString}; use jvm_rust::ClassDefinitionImpl; @@ -16,11 +16,11 @@ impl TestClass { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Runnable"], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("run", "()V", Self::run, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("run", "()V", Self::run, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("ran", "Z", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("ran", "Z", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/tests/classes/java/util/test_arrays.rs b/java_runtime/tests/classes/java/util/test_arrays.rs index f8b67de3..aee46d93 100644 --- a/java_runtime/tests/classes/java/util/test_arrays.rs +++ b/java_runtime/tests/classes/java/util/test_arrays.rs @@ -17,15 +17,15 @@ impl ArraysSortValue { parent_class: Some("java/lang/Object"), interfaces: vec!["java/lang/Comparable"], methods: vec![ - JavaMethodProto::new("", "(IIZ)V", Self::init, Default::default()), + JavaMethodProto::new("", "(IIZ)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new("compareTo", "(Ljava/lang/Object;)I", Self::compare_to, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("key", "I", Default::default()), - JavaFieldProto::new("id", "I", Default::default()), - JavaFieldProto::new("fail", "Z", Default::default()), + JavaFieldProto::new("key", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("id", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("fail", "Z", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -62,7 +62,7 @@ impl ArraysComparator { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Comparator"], methods: vec![ - JavaMethodProto::new("", "(ZZ)V", Self::init, Default::default()), + JavaMethodProto::new("", "(ZZ)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new( "compare", "(Ljava/lang/Object;Ljava/lang/Object;)I", @@ -71,10 +71,10 @@ impl ArraysComparator { ), ], fields: vec![ - JavaFieldProto::new("reverse", "Z", Default::default()), - JavaFieldProto::new("fail", "Z", Default::default()), + JavaFieldProto::new("reverse", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("fail", "Z", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -118,11 +118,11 @@ impl ArraysEqualsProbe { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(Z)V", Self::init, Default::default()), + JavaMethodProto::new("", "(Z)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("result", "Z", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("result", "Z", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/tests/classes/java/util/test_collection_contracts.rs b/java_runtime/tests/classes/java/util/test_collection_contracts.rs index bde68800..b52ee978 100644 --- a/java_runtime/tests/classes/java/util/test_collection_contracts.rs +++ b/java_runtime/tests/classes/java/util/test_collection_contracts.rs @@ -1,7 +1,7 @@ use alloc::{boxed::Box, collections::BTreeMap, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use java_runtime::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object, get_runtime_class_proto}; use jvm::{Array, ClassInstanceRef, JavaError, Jvm, Result, runtime::JavaLangString}; use jvm_rust::ClassDefinitionImpl; @@ -21,7 +21,7 @@ impl SnapshotCollection { JavaMethodProto::new("size", "()I", Self::size, MethodAccessFlags::PUBLIC), JavaMethodProto::new("iterator", "()Ljava/util/Iterator;", Self::iterator, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("elements", "[Ljava/lang/Object;", Default::default())], + fields: vec![JavaFieldProto::new("elements", "[Ljava/lang/Object;", FieldAccessFlags::PRIVATE)], access_flags: ClassAccessFlags::PUBLIC, } } @@ -57,8 +57,8 @@ impl SnapshotIterator { JavaMethodProto::new("remove", "()V", Self::remove, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("elements", "[Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("index", "I", Default::default()), + JavaFieldProto::new("elements", "[Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("index", "I", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } @@ -169,8 +169,8 @@ impl ConfigurableEqualsValue { JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("result", "Z", Default::default()), - JavaFieldProto::new("equalsCalls", "I", Default::default()), + JavaFieldProto::new("result", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("equalsCalls", "I", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } @@ -214,12 +214,12 @@ impl StatefulMapEntry { ), ], fields: vec![ - JavaFieldProto::new("firstKey", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("laterKey", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("value", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("mode", "I", Default::default()), - JavaFieldProto::new("keyCalls", "I", Default::default()), - JavaFieldProto::new("valueCalls", "I", Default::default()), + JavaFieldProto::new("firstKey", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("laterKey", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("value", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("mode", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("keyCalls", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("valueCalls", "I", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } @@ -291,8 +291,8 @@ impl ThrowingMap { JavaMethodProto::new("get", "(Ljava/lang/Object;)Ljava/lang/Object;", Self::get, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("size", "I", Default::default()), - JavaFieldProto::new("mode", "I", Default::default()), + JavaFieldProto::new("size", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("mode", "I", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/tests/classes/java/util/test_collections.rs b/java_runtime/tests/classes/java/util/test_collections.rs index 49580ca4..220a131e 100644 --- a/java_runtime/tests/classes/java/util/test_collections.rs +++ b/java_runtime/tests/classes/java/util/test_collections.rs @@ -21,11 +21,11 @@ impl CollectionsSortValue { JavaMethodProto::new("compareTo", "(Ljava/lang/Object;)I", Self::compare_to, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("key", "I", Default::default()), - JavaFieldProto::new("id", "I", Default::default()), - JavaFieldProto::new("fail", "Z", Default::default()), + JavaFieldProto::new("key", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("id", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("fail", "Z", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -73,11 +73,11 @@ impl CollectionsComparator { ), ], fields: vec![ - JavaFieldProto::new("reverse", "Z", Default::default()), - JavaFieldProto::new("fail", "Z", Default::default()), - JavaFieldProto::new("allowNull", "Z", Default::default()), + JavaFieldProto::new("reverse", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("fail", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("allowNull", "Z", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -162,11 +162,11 @@ impl CollectionsProbeList { ), ], fields: vec![ - JavaFieldProto::new("elements", "[Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("listIteratorCalls", "I", Default::default()), - JavaFieldProto::new("setCalls", "I", Default::default()), + JavaFieldProto::new("elements", "[Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("listIteratorCalls", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("setCalls", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -247,8 +247,8 @@ impl CollectionsInvalidRandom { JavaMethodProto::new("", "(I)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new("nextInt", "(I)I", Self::next_int, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("result", "I", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("result", "I", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::empty(), } } @@ -277,10 +277,10 @@ impl CollectionsExceptionalSet { JavaMethodProto::new("contains", "(Ljava/lang/Object;)Z", Self::contains, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("element", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("mode", "I", Default::default()), + JavaFieldProto::new("element", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("mode", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -335,8 +335,8 @@ impl CollectionsAsymmetricEquals { JavaMethodProto::new("", "(Z)V", Self::init, MethodAccessFlags::PUBLIC), JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("result", "Z", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("result", "Z", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::empty(), } } @@ -363,11 +363,11 @@ impl CollectionsEqualsProbe { JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("result", "Z", Default::default()), - JavaFieldProto::new("fail", "Z", Default::default()), - JavaFieldProto::new("equalsCalls", "I", Default::default()), + JavaFieldProto::new("result", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("fail", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("equalsCalls", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -413,15 +413,15 @@ impl CollectionsEntryProbe { ), ], fields: vec![ - JavaFieldProto::new("key", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("value", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("throwKey", "Z", Default::default()), - JavaFieldProto::new("throwValue", "Z", Default::default()), - JavaFieldProto::new("keyCalls", "I", Default::default()), - JavaFieldProto::new("valueCalls", "I", Default::default()), - JavaFieldProto::new("setValueCalls", "I", Default::default()), + JavaFieldProto::new("key", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("value", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("throwKey", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("throwValue", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("keyCalls", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("valueCalls", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("setValueCalls", "I", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/tests/classes/java/util/test_hash_map.rs b/java_runtime/tests/classes/java/util/test_hash_map.rs index e5b502b5..c44e15a1 100644 --- a/java_runtime/tests/classes/java/util/test_hash_map.rs +++ b/java_runtime/tests/classes/java/util/test_hash_map.rs @@ -1,6 +1,7 @@ use alloc::{boxed::Box, collections::BTreeMap, vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use java_runtime::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object, classes::java::util::HashMapEntry}; use jvm::{Array, ClassInstanceRef, JavaError, Jvm, Result, runtime::JavaLangString}; use jvm_rust::ClassDefinitionImpl; @@ -16,12 +17,12 @@ impl AsymmetricStoredKey { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("hashCode", "()I", Self::hash_code, Default::default()), - JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -49,12 +50,12 @@ impl AsymmetricQueryKey { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "()V", Self::init, Default::default()), - JavaMethodProto::new("hashCode", "()I", Self::hash_code, Default::default()), - JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, Default::default()), + JavaMethodProto::new("", "()V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), ], fields: vec![], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } @@ -86,12 +87,12 @@ impl CollisionKey { parent_class: Some("java/lang/Object"), interfaces: vec![], methods: vec![ - JavaMethodProto::new("", "(I)V", Self::init, Default::default()), - JavaMethodProto::new("hashCode", "()I", Self::hash_code, Default::default()), - JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, Default::default()), + JavaMethodProto::new("", "(I)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC), ], - fields: vec![JavaFieldProto::new("id", "I", Default::default())], - access_flags: Default::default(), + fields: vec![JavaFieldProto::new("id", "I", FieldAccessFlags::PRIVATE)], + access_flags: ClassAccessFlags::empty(), } } @@ -127,16 +128,21 @@ impl CustomMapEntry { parent_class: Some("java/lang/Object"), interfaces: vec!["java/util/Map$Entry"], methods: vec![ - JavaMethodProto::new("", "(Ljava/lang/Object;Ljava/lang/Object;)V", Self::init, Default::default()), - JavaMethodProto::new("getKey", "()Ljava/lang/Object;", Self::get_key, Default::default()), - JavaMethodProto::new("getValue", "()Ljava/lang/Object;", Self::get_value, Default::default()), - JavaMethodProto::new("setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", Self::set_value, Default::default()), + JavaMethodProto::new("", "(Ljava/lang/Object;Ljava/lang/Object;)V", Self::init, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getKey", "()Ljava/lang/Object;", Self::get_key, MethodAccessFlags::PUBLIC), + JavaMethodProto::new("getValue", "()Ljava/lang/Object;", Self::get_value, MethodAccessFlags::PUBLIC), + JavaMethodProto::new( + "setValue", + "(Ljava/lang/Object;)Ljava/lang/Object;", + Self::set_value, + MethodAccessFlags::PUBLIC, + ), ], fields: vec![ - JavaFieldProto::new("key", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("value", "Ljava/lang/Object;", Default::default()), + JavaFieldProto::new("key", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("value", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), ], - access_flags: Default::default(), + access_flags: ClassAccessFlags::empty(), } } diff --git a/java_runtime/tests/classes/java/util/test_linked_hash_map.rs b/java_runtime/tests/classes/java/util/test_linked_hash_map.rs index 499cc5e3..bcbe7595 100644 --- a/java_runtime/tests/classes/java/util/test_linked_hash_map.rs +++ b/java_runtime/tests/classes/java/util/test_linked_hash_map.rs @@ -1,7 +1,7 @@ use alloc::{boxed::Box, collections::BTreeMap, vec, vec::Vec}; use java_class_proto::{JavaFieldProto, JavaMethodProto}; -use java_constants::{ClassAccessFlags, MethodAccessFlags}; +use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags}; use java_runtime::{RuntimeClassProto, RuntimeContext, classes::java::lang::Object, get_runtime_class_proto}; use jvm::{Array, ClassInstanceRef, JavaError, Jvm, Result, runtime::JavaLangString}; use jvm_rust::ClassDefinitionImpl; @@ -26,8 +26,8 @@ impl LimitedLinkedHashMap { ), ], fields: vec![ - JavaFieldProto::new("limit", "I", Default::default()), - JavaFieldProto::new("callbacks", "I", Default::default()), + JavaFieldProto::new("limit", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("callbacks", "I", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } diff --git a/java_runtime/tests/classes/java/util/test_tree_map.rs b/java_runtime/tests/classes/java/util/test_tree_map.rs index 6c918ade..107312e1 100644 --- a/java_runtime/tests/classes/java/util/test_tree_map.rs +++ b/java_runtime/tests/classes/java/util/test_tree_map.rs @@ -35,9 +35,9 @@ impl TreeTestComparator { ), ], fields: vec![ - JavaFieldProto::new("reverse", "Z", Default::default()), - JavaFieldProto::new("allowNull", "Z", Default::default()), - JavaFieldProto::new("absolute", "Z", Default::default()), + JavaFieldProto::new("reverse", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("allowNull", "Z", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("absolute", "Z", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } @@ -109,8 +109,8 @@ impl TreeDirectionalKey { JavaMethodProto::new("compareTo", "(Ljava/lang/Object;)I", Self::compare_to, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("value", "I", Default::default()), - JavaFieldProto::new("fail", "Z", Default::default()), + JavaFieldProto::new("value", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("fail", "Z", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } @@ -150,8 +150,8 @@ impl TreeEqualsValue { JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("group", "I", Default::default()), - JavaFieldProto::new("answer", "Z", Default::default()), + JavaFieldProto::new("group", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("answer", "Z", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } @@ -205,10 +205,10 @@ impl TreeChangingEntry { JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("firstKey", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("secondKey", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("value", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("keyCalls", "I", Default::default()), + JavaFieldProto::new("firstKey", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("secondKey", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("value", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("keyCalls", "I", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, } @@ -289,10 +289,10 @@ impl TreeValueProbeEntry { JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC), ], fields: vec![ - JavaFieldProto::new("key", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("value", "Ljava/lang/Object;", Default::default()), - JavaFieldProto::new("valueCalls", "I", Default::default()), - JavaFieldProto::new("throwValue", "Z", Default::default()), + JavaFieldProto::new("key", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("value", "Ljava/lang/Object;", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("valueCalls", "I", FieldAccessFlags::PRIVATE), + JavaFieldProto::new("throwValue", "Z", FieldAccessFlags::PRIVATE), ], access_flags: ClassAccessFlags::PUBLIC, }