1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Macro example: Using jvmrs-macros to define Java classes in Rust
//
// This example demonstrates the procedural macro system for defining
// Java-compatible structures in Rust.
//
// Note: This requires the jvmrs-macros crate to be properly set up.
// Add to Cargo.toml:
// [dependencies]
// jvmrs = { path = "..", features = ["interop"] }
// jvmrs-macros = { path = "../jvmrs-macros" }
// Uncomment these when jvmrs-macros is properly integrated
/*
use jvmrs::memory::Value;
use jvmrs_macros::{java_class, java_native};
// Define a Java class using the macro
#[java_class("com.example.Counter")]
pub struct Counter {
#[java_field]
pub count: i32,
}
impl Counter {
pub fn new() -> Self {
Counter { count: 0 }
}
pub fn increment(&mut self) -> i32 {
self.count += 1;
self.count
}
pub fn add(&mut self, value: i32) -> i32 {
self.count += value;
self.count
}
pub fn get(&self) -> i32 {
self.count
}
}
// Register native methods that can be called from Java
#[java_native("com.example.Utils", "addNumbers")]
pub fn add_numbers(args: &[Value]) -> Result<Value, String> {
if args.len() >= 2 {
let a = args[0].as_int();
let b = args[1].as_int();
Ok(Value::Int(a + b))
} else {
Err("Expected 2 integer arguments".to_string())
}
}
#[java_native("com.example.Utils", "multiplyNumbers")]
pub fn multiply_numbers(args: &[Value]) -> Result<Value, String> {
if args.len() >= 2 {
let a = args[0].as_int();
let b = args[1].as_int();
Ok(Value::Int(a * b))
} else {
Err("Expected 2 integer arguments".to_string())
}
}
#[java_native("com.example.StringUtils", "reverse")]
pub fn reverse_string(args: &[Value]) -> Result<Value, String> {
if args.len() >= 1 {
if let Value::Reference(addr) = args[0] {
// This would need actual heap access to get the string content
// For now, return a placeholder
Ok(Value::Null)
} else {
Err("Expected a string reference".to_string())
}
} else {
Err("Expected 1 argument".to_string())
}
}
#[java_native("com.example.ArrayUtils", "sumArray")]
pub fn sum_array(args: &[Value]) -> Result<Value, String> {
if args.len() >= 1 {
if let Value::ArrayRef(addr) = args[0] {
// This would need actual heap access to get the array content
// For now, return a placeholder
Ok(Value::Int(0))
} else {
Err("Expected an array reference".to_string())
}
} else {
Err("Expected 1 argument".to_string())
}
}
fn main() {
println!("=== JVMRS Macro System Example ===\n");
// Demonstrate the Java class
println!("1. Using the Java-class-like Counter struct:");
let mut counter = Counter::new();
println!(" Initial count: {}", counter.get());
println!(" After increment: {}", counter.increment());
println!(" After adding 5: {}", counter.add(5));
println!(" Final count: {}", counter.get());
println!("\n2. Native methods are automatically registered:");
println!(" - com.example.Utils.addNumbers(int, int) -> int");
println!(" - com.example.Utils.multiplyNumbers(int, int) -> int");
println!(" - com.example.StringUtils.reverse(String) -> String");
println!(" - com.example.ArrayUtils.sumArray(int[]) -> int");
println!("\n3. These can be called from Java bytecode:");
println!(" // Java code:");
println!(" // int sum = Utils.addNumbers(10, 20);");
println!(" // int product = Utils.multiplyNumbers(5, 6);");
println!("\n=== Benefits of the macro system ===");
println!("✓ Type-safe Java/Rust interop");
println!("✓ Automatic native method registration");
println!("✓ Compile-time error checking");
println!("✓ No manual JNI boilerplate");
println!("✓ IDE autocomplete support");
}
*/