Skip to content

Commit d80e4cc

Browse files
committed
Add Java primitive wrapper classes
1 parent fe5d116 commit d80e4cc

25 files changed

Lines changed: 4858 additions & 66 deletions

java_runtime/src/classes/java/lang.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,43 @@ mod abstract_method_error;
22
mod arithmetic_exception;
33
mod array_index_out_of_bounds_exception;
44
mod array_store_exception;
5+
mod boolean;
6+
mod byte;
7+
mod character;
58
mod class;
69
mod class_cast_exception;
710
mod class_loader;
811
mod class_not_found_exception;
912
mod clone_not_supported_exception;
1013
mod cloneable;
1114
mod comparable;
15+
mod double;
1216
mod error;
1317
mod exception;
1418
mod exception_in_initializer_error;
19+
mod float;
1520
mod illegal_argument_exception;
1621
mod incompatible_class_change_error;
1722
mod index_out_of_bounds_exception;
1823
mod instantiation_error;
1924
mod integer;
2025
mod interrupted_exception;
2126
mod linkage_error;
27+
mod long;
2228
mod math;
2329
mod negative_array_size_exception;
2430
mod no_class_def_found_error;
2531
mod no_such_field_error;
2632
mod no_such_method_error;
2733
mod null_pointer_exception;
34+
mod number;
2835
mod number_format_exception;
2936
mod object;
3037
mod runnable;
3138
mod runtime;
3239
mod runtime_exception;
3340
mod security_exception;
41+
mod short;
3442
mod string;
3543
mod string_buffer;
3644
mod string_index_out_of_bounds_exception;
@@ -41,15 +49,17 @@ mod unsupported_operation_exception;
4149

4250
pub use self::{
4351
abstract_method_error::AbstractMethodError, arithmetic_exception::ArithmeticException,
44-
array_index_out_of_bounds_exception::ArrayIndexOutOfBoundsException, array_store_exception::ArrayStoreException, class::Class,
45-
class_cast_exception::ClassCastException, class_loader::ClassLoader, class_not_found_exception::ClassNotFoundException,
46-
clone_not_supported_exception::CloneNotSupportedException, cloneable::Cloneable, comparable::Comparable, error::Error, exception::Exception,
47-
exception_in_initializer_error::ExceptionInInitializerError, illegal_argument_exception::IllegalArgumentException,
48-
incompatible_class_change_error::IncompatibleClassChangeError, index_out_of_bounds_exception::IndexOutOfBoundsException,
49-
instantiation_error::InstantiationError, integer::Integer, interrupted_exception::InterruptedException, linkage_error::LinkageError, math::Math,
52+
array_index_out_of_bounds_exception::ArrayIndexOutOfBoundsException, array_store_exception::ArrayStoreException, boolean::Boolean, byte::Byte,
53+
character::Character, class::Class, class_cast_exception::ClassCastException, class_loader::ClassLoader,
54+
class_not_found_exception::ClassNotFoundException, clone_not_supported_exception::CloneNotSupportedException, cloneable::Cloneable,
55+
comparable::Comparable, double::Double, error::Error, exception::Exception, exception_in_initializer_error::ExceptionInInitializerError,
56+
float::Float, illegal_argument_exception::IllegalArgumentException, incompatible_class_change_error::IncompatibleClassChangeError,
57+
index_out_of_bounds_exception::IndexOutOfBoundsException, instantiation_error::InstantiationError, integer::Integer,
58+
interrupted_exception::InterruptedException, linkage_error::LinkageError, long::Long, math::Math,
5059
negative_array_size_exception::NegativeArraySizeException, no_class_def_found_error::NoClassDefFoundError, no_such_field_error::NoSuchFieldError,
51-
no_such_method_error::NoSuchMethodError, null_pointer_exception::NullPointerException, number_format_exception::NumberFormatException,
52-
object::Object, runnable::Runnable, runtime::Runtime, runtime_exception::RuntimeException, security_exception::SecurityException, string::String,
53-
string_buffer::StringBuffer, string_index_out_of_bounds_exception::StringIndexOutOfBoundsException, system::System, thread::Thread,
54-
throwable::Throwable, unsupported_operation_exception::UnsupportedOperationException,
60+
no_such_method_error::NoSuchMethodError, null_pointer_exception::NullPointerException, number::Number,
61+
number_format_exception::NumberFormatException, object::Object, runnable::Runnable, runtime::Runtime, runtime_exception::RuntimeException,
62+
security_exception::SecurityException, short::Short, string::String, string_buffer::StringBuffer,
63+
string_index_out_of_bounds_exception::StringIndexOutOfBoundsException, system::System, thread::Thread, throwable::Throwable,
64+
unsupported_operation_exception::UnsupportedOperationException,
5565
};
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
use alloc::vec;
2+
3+
use java_class_proto::{JavaFieldProto, JavaMethodProto};
4+
use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags};
5+
use jvm::{
6+
ClassInstanceRef, Jvm, Result,
7+
runtime::{JavaLangClass, JavaLangString},
8+
};
9+
10+
use crate::{
11+
RuntimeClassProto, RuntimeContext,
12+
classes::java::lang::{Object, String},
13+
};
14+
15+
// public final class java.lang.Boolean
16+
pub struct Boolean;
17+
18+
impl Boolean {
19+
pub fn as_proto() -> RuntimeClassProto {
20+
RuntimeClassProto {
21+
name: "java/lang/Boolean",
22+
parent_class: Some("java/lang/Object"),
23+
interfaces: vec!["java/io/Serializable"],
24+
methods: vec![
25+
JavaMethodProto::new("<clinit>", "()V", Self::clinit, MethodAccessFlags::STATIC),
26+
JavaMethodProto::new("<init>", "(Z)V", Self::init, MethodAccessFlags::PUBLIC),
27+
JavaMethodProto::new("<init>", "(Ljava/lang/String;)V", Self::init_string, MethodAccessFlags::PUBLIC),
28+
JavaMethodProto::new("booleanValue", "()Z", Self::boolean_value, MethodAccessFlags::PUBLIC),
29+
JavaMethodProto::new(
30+
"valueOf",
31+
"(Ljava/lang/String;)Ljava/lang/Boolean;",
32+
Self::value_of_string,
33+
MethodAccessFlags::PUBLIC | MethodAccessFlags::STATIC,
34+
),
35+
JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, MethodAccessFlags::PUBLIC),
36+
JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC),
37+
JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC),
38+
JavaMethodProto::new(
39+
"getBoolean",
40+
"(Ljava/lang/String;)Z",
41+
Self::get_boolean,
42+
MethodAccessFlags::PUBLIC | MethodAccessFlags::STATIC,
43+
),
44+
],
45+
fields: vec![
46+
JavaFieldProto::new(
47+
"TRUE",
48+
"Ljava/lang/Boolean;",
49+
FieldAccessFlags::PUBLIC | FieldAccessFlags::STATIC | FieldAccessFlags::FINAL,
50+
),
51+
JavaFieldProto::new(
52+
"FALSE",
53+
"Ljava/lang/Boolean;",
54+
FieldAccessFlags::PUBLIC | FieldAccessFlags::STATIC | FieldAccessFlags::FINAL,
55+
),
56+
JavaFieldProto::new(
57+
"TYPE",
58+
"Ljava/lang/Class;",
59+
FieldAccessFlags::PUBLIC | FieldAccessFlags::STATIC | FieldAccessFlags::FINAL,
60+
),
61+
JavaFieldProto::new("value", "Z", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL),
62+
],
63+
access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::FINAL,
64+
}
65+
}
66+
67+
async fn clinit(jvm: &Jvm, _: &mut RuntimeContext) -> Result<()> {
68+
let value = jvm.new_class("java/lang/Boolean", "(Z)V", (true,)).await?;
69+
jvm.put_static_field("java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;", value).await?;
70+
71+
let value = jvm.new_class("java/lang/Boolean", "(Z)V", (false,)).await?;
72+
jvm.put_static_field("java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;", value).await?;
73+
74+
jvm.put_static_field(
75+
"java/lang/Boolean",
76+
"TYPE",
77+
"Ljava/lang/Class;",
78+
JavaLangClass::from_rust_primitive(jvm, "boolean").await?,
79+
)
80+
.await
81+
}
82+
83+
async fn init(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef<Self>, value: bool) -> Result<()> {
84+
let _: () = jvm.invoke_special(&this, "java/lang/Object", "<init>", "()V", ()).await?;
85+
jvm.put_field(&mut this, "value", "Z", value).await
86+
}
87+
88+
async fn init_string(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef<Self>, value: ClassInstanceRef<String>) -> Result<()> {
89+
let parsed = if value.is_null() {
90+
false
91+
} else {
92+
JavaLangString::to_rust_string(jvm, &value).await?.eq_ignore_ascii_case("true")
93+
};
94+
95+
let _: () = jvm.invoke_special(&this, "java/lang/Object", "<init>", "()V", ()).await?;
96+
jvm.put_field(&mut this, "value", "Z", parsed).await
97+
}
98+
99+
async fn boolean_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<bool> {
100+
jvm.get_field(&this, "value", "Z").await
101+
}
102+
103+
async fn value_of_string(jvm: &Jvm, _: &mut RuntimeContext, value: ClassInstanceRef<String>) -> Result<ClassInstanceRef<Self>> {
104+
let parsed = if value.is_null() {
105+
false
106+
} else {
107+
JavaLangString::to_rust_string(jvm, &value).await?.eq_ignore_ascii_case("true")
108+
};
109+
110+
if parsed {
111+
jvm.get_static_field("java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;").await
112+
} else {
113+
jvm.get_static_field("java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;").await
114+
}
115+
}
116+
117+
async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<ClassInstanceRef<String>> {
118+
let value: bool = jvm.invoke_virtual(&this, "booleanValue", "()Z", ()).await?;
119+
Ok(JavaLangString::from_rust_string(jvm, if value { "true" } else { "false" }).await?.into())
120+
}
121+
122+
async fn hash_code(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<i32> {
123+
let value: bool = jvm.invoke_virtual(&this, "booleanValue", "()Z", ()).await?;
124+
Ok(if value { 1231 } else { 1237 })
125+
}
126+
127+
async fn equals(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>, other: ClassInstanceRef<Object>) -> Result<bool> {
128+
if other.is_null() || !jvm.is_instance(&**other, "java/lang/Boolean") {
129+
return Ok(false);
130+
}
131+
132+
let this_value: bool = jvm.invoke_virtual(&this, "booleanValue", "()Z", ()).await?;
133+
let other_value: bool = jvm.invoke_virtual(&other, "booleanValue", "()Z", ()).await?;
134+
Ok(this_value == other_value)
135+
}
136+
137+
async fn get_boolean(jvm: &Jvm, _: &mut RuntimeContext, name: ClassInstanceRef<String>) -> Result<bool> {
138+
if name.is_null() {
139+
return Ok(false);
140+
}
141+
142+
let value: ClassInstanceRef<String> = jvm
143+
.invoke_static("java/lang/System", "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (name,))
144+
.await?;
145+
if value.is_null() {
146+
return Ok(false);
147+
}
148+
149+
Ok(JavaLangString::to_rust_string(jvm, &value).await?.eq_ignore_ascii_case("true"))
150+
}
151+
}

0 commit comments

Comments
 (0)