Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add implementation of String.intern() method #56

Merged
merged 1 commit into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ fn should_do_strings_cpool_advanced() {
let last_frame_value = vm
.run("samples.javacore.strings.cpool.advanced.StringPoolAdvanced")
.unwrap();
assert_eq!(29, get_int(last_frame_value))
assert_eq!(127, get_int(last_frame_value))
}

#[test]
Expand Down
19 changes: 9 additions & 10 deletions tests/test_data/StringPoolAdvanced.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static void main(String[] args) {
// Example 1: Creating a string with new keyword
String str3 = new String("Hello");
// str3 is created in the heap, not in the string pool
int bit1 = str1 == str3 ? 1 : 0;
int bit1 = str1 != str3 ? 1 : 0;

// Example 2: Comparing strings with equals method
int bit2 = str1.equals(str3) ? 1 : 0;
Expand All @@ -24,23 +24,22 @@ public static void main(String[] args) {
String str4 = new AnotherClass().getAnotherString();
int bit4 = str1 == str4 ? 1 : 0;

// Example X: Concatenation with non-literals at runtime
//String part1 = "Hel";
//String part2 = "lo";
//String str6 = part1 + part2; // New object is created in the heap
//System.out.println("str1 == str6 : " + (str1 == str6)); // false
// Example 5: Interning the string (forcing it into the pool)
String str6 = str3.intern();
int bit5 = str1 == str6 ? 1 : 0;

// Example X: Interning the string (forcing it into the pool)
//String str4 = str3.intern();
// Now str4 refers to the string from the pool
//System.out.println("str1 == str4 : " + (str1 == str4)); // true
// Example 6: Creation in runtime
String str7 = new String(new char[] {'H', 'e', 'l', 'l', 'o'}); // New object is created in the heap
int bit6 = str1 != str7 ? 1 : 0;

int result = 0;
result = setBit(result, 0, bit0);
result = setBit(result, 1, bit1);
result = setBit(result, 2, bit2);
result = setBit(result, 3, bit3);
result = setBit(result, 4, bit4);
result = setBit(result, 5, bit5);
result = setBit(result, 6, bit6);
}

private static int setBit(int num, int position, int value) {
Expand Down
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion vm/src/execution_engine/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub(crate) mod engine;
pub(crate) mod ldc_resolution_manager;
pub(crate) mod opcode;
mod string_pool_helper;
pub(crate) mod string_pool_helper;
mod system_native_table;
5 changes: 5 additions & 0 deletions vm/src/execution_engine/system_native_table.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::error::Error;
use crate::system_native::class::{get_modifiers_wrp, get_primitive_class_wrp};
use crate::system_native::string::intern_wrp;
use crate::system_native::system::{arraycopy_wrp, current_time_millis_wrp};
use once_cell::sync::Lazy;
use std::collections::HashMap;
Expand Down Expand Up @@ -32,6 +33,10 @@ static SYSTEM_NATIVE_TABLE: Lazy<
"jdk/internal/misc/Unsafe:registerNatives:()V",
void_stub as fn(&[i32]) -> crate::error::Result<Vec<i32>>,
);
table.insert(
"java/lang/String:intern:()Ljava/lang/String;",
intern_wrp as fn(&[i32]) -> crate::error::Result<Vec<i32>>,
);

table
});
Expand Down
2 changes: 1 addition & 1 deletion vm/src/system_native/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub(crate) mod class;
mod string;
pub(crate) mod string;
pub(crate) mod system;
11 changes: 11 additions & 0 deletions vm/src/system_native/string.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::execution_engine::string_pool_helper::StringPoolHelper;
use crate::heap::heap::with_heap_read_lock;

const STRING_CLASS_NAME: &str = "java/lang/String";
Expand Down Expand Up @@ -34,3 +35,13 @@ pub(crate) fn get_utf8_string_by_ref(string_ref: i32) -> crate::error::Result<St

Ok(result)
}

pub(crate) fn intern_wrp(args: &[i32]) -> crate::error::Result<Vec<i32>> {
let reference = intern(args[0])?;
Ok(vec![reference])
}
fn intern(reference: i32) -> crate::error::Result<i32> {
let string = get_utf8_string_by_ref(reference)?;

StringPoolHelper::get_string(string)
}