Skip to content

Commit

Permalink
Add implementation of String.intern() method
Browse files Browse the repository at this point in the history
  • Loading branch information
hextriclosan committed Oct 17, 2024
1 parent 05a1759 commit 073edd7
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 13 deletions.
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)
}

0 comments on commit 073edd7

Please sign in to comment.