Skip to content
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
30 changes: 20 additions & 10 deletions java_runtime/src/classes/java/lang.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,35 +2,43 @@ mod abstract_method_error;
mod arithmetic_exception;
mod array_index_out_of_bounds_exception;
mod array_store_exception;
mod boolean;
mod byte;
mod character;
mod class;
mod class_cast_exception;
mod class_loader;
mod class_not_found_exception;
mod clone_not_supported_exception;
mod cloneable;
mod comparable;
mod double;
mod error;
mod exception;
mod exception_in_initializer_error;
mod float;
mod illegal_argument_exception;
mod incompatible_class_change_error;
mod index_out_of_bounds_exception;
mod instantiation_error;
mod integer;
mod interrupted_exception;
mod linkage_error;
mod long;
mod math;
mod negative_array_size_exception;
mod no_class_def_found_error;
mod no_such_field_error;
mod no_such_method_error;
mod null_pointer_exception;
mod number;
mod number_format_exception;
mod object;
mod runnable;
mod runtime;
mod runtime_exception;
mod security_exception;
mod short;
mod string;
mod string_buffer;
mod string_index_out_of_bounds_exception;
Expand All@@ -41,15 +49,17 @@ mod unsupported_operation_exception;

pub use self::{
abstract_method_error::AbstractMethodError, arithmetic_exception::ArithmeticException,
array_index_out_of_bounds_exception::ArrayIndexOutOfBoundsException, array_store_exception::ArrayStoreException, class::Class,
class_cast_exception::ClassCastException, class_loader::ClassLoader, class_not_found_exception::ClassNotFoundException,
clone_not_supported_exception::CloneNotSupportedException, cloneable::Cloneable, comparable::Comparable, error::Error, exception::Exception,
exception_in_initializer_error::ExceptionInInitializerError, illegal_argument_exception::IllegalArgumentException,
incompatible_class_change_error::IncompatibleClassChangeError, index_out_of_bounds_exception::IndexOutOfBoundsException,
instantiation_error::InstantiationError, integer::Integer, interrupted_exception::InterruptedException, linkage_error::LinkageError, math::Math,
array_index_out_of_bounds_exception::ArrayIndexOutOfBoundsException, array_store_exception::ArrayStoreException, boolean::Boolean, byte::Byte,
character::Character, class::Class, class_cast_exception::ClassCastException, class_loader::ClassLoader,
class_not_found_exception::ClassNotFoundException, clone_not_supported_exception::CloneNotSupportedException, cloneable::Cloneable,
comparable::Comparable, double::Double, error::Error, exception::Exception, exception_in_initializer_error::ExceptionInInitializerError,
float::Float, illegal_argument_exception::IllegalArgumentException, incompatible_class_change_error::IncompatibleClassChangeError,
index_out_of_bounds_exception::IndexOutOfBoundsException, instantiation_error::InstantiationError, integer::Integer,
interrupted_exception::InterruptedException, linkage_error::LinkageError, long::Long, math::Math,
negative_array_size_exception::NegativeArraySizeException, no_class_def_found_error::NoClassDefFoundError, no_such_field_error::NoSuchFieldError,
no_such_method_error::NoSuchMethodError, null_pointer_exception::NullPointerException, number_format_exception::NumberFormatException,
object::Object, runnable::Runnable, runtime::Runtime, runtime_exception::RuntimeException, security_exception::SecurityException, string::String,
string_buffer::StringBuffer, string_index_out_of_bounds_exception::StringIndexOutOfBoundsException, system::System, thread::Thread,
throwable::Throwable, unsupported_operation_exception::UnsupportedOperationException,
no_such_method_error::NoSuchMethodError, null_pointer_exception::NullPointerException, number::Number,
number_format_exception::NumberFormatException, object::Object, runnable::Runnable, runtime::Runtime, runtime_exception::RuntimeException,
security_exception::SecurityException, short::Short, string::String, string_buffer::StringBuffer,
string_index_out_of_bounds_exception::StringIndexOutOfBoundsException, system::System, thread::Thread, throwable::Throwable,
unsupported_operation_exception::UnsupportedOperationException,
};
151 changes: 151 additions & 0 deletions java_runtime/src/classes/java/lang/boolean.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
use alloc::vec;

use java_class_proto::{JavaFieldProto, JavaMethodProto};
use java_constants::{ClassAccessFlags, FieldAccessFlags, MethodAccessFlags};
use jvm::{
ClassInstanceRef, Jvm, Result,
runtime::{JavaLangClass, JavaLangString},
};

use crate::{
RuntimeClassProto, RuntimeContext,
classes::java::lang::{Object, String},
};

// public final class java.lang.Boolean
pub struct Boolean;

impl Boolean {
pub fn as_proto() -> RuntimeClassProto {
RuntimeClassProto {
name: "java/lang/Boolean",
parent_class: Some("java/lang/Object"),
interfaces: vec!["java/io/Serializable"],
methods: vec![
JavaMethodProto::new("<clinit>", "()V", Self::clinit, MethodAccessFlags::STATIC),
JavaMethodProto::new("<init>", "(Z)V", Self::init, MethodAccessFlags::PUBLIC),
JavaMethodProto::new("<init>", "(Ljava/lang/String;)V", Self::init_string, MethodAccessFlags::PUBLIC),
JavaMethodProto::new("booleanValue", "()Z", Self::boolean_value, MethodAccessFlags::PUBLIC),
JavaMethodProto::new(
"valueOf",
"(Ljava/lang/String;)Ljava/lang/Boolean;",
Self::value_of_string,
MethodAccessFlags::PUBLIC | MethodAccessFlags::STATIC,
),
JavaMethodProto::new("toString", "()Ljava/lang/String;", Self::to_string, MethodAccessFlags::PUBLIC),
JavaMethodProto::new("hashCode", "()I", Self::hash_code, MethodAccessFlags::PUBLIC),
JavaMethodProto::new("equals", "(Ljava/lang/Object;)Z", Self::equals, MethodAccessFlags::PUBLIC),
JavaMethodProto::new(
"getBoolean",
"(Ljava/lang/String;)Z",
Self::get_boolean,
MethodAccessFlags::PUBLIC | MethodAccessFlags::STATIC,
),
],
fields: vec![
JavaFieldProto::new(
"TRUE",
"Ljava/lang/Boolean;",
FieldAccessFlags::PUBLIC | FieldAccessFlags::STATIC | FieldAccessFlags::FINAL,
),
JavaFieldProto::new(
"FALSE",
"Ljava/lang/Boolean;",
FieldAccessFlags::PUBLIC | FieldAccessFlags::STATIC | FieldAccessFlags::FINAL,
),
JavaFieldProto::new(
"TYPE",
"Ljava/lang/Class;",
FieldAccessFlags::PUBLIC | FieldAccessFlags::STATIC | FieldAccessFlags::FINAL,
),
JavaFieldProto::new("value", "Z", FieldAccessFlags::PRIVATE | FieldAccessFlags::FINAL),
],
access_flags: ClassAccessFlags::PUBLIC | ClassAccessFlags::FINAL,
}
}

async fn clinit(jvm: &Jvm, _: &mut RuntimeContext) -> Result<()> {
let value = jvm.new_class("java/lang/Boolean", "(Z)V", (true,)).await?;
jvm.put_static_field("java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;", value).await?;

let value = jvm.new_class("java/lang/Boolean", "(Z)V", (false,)).await?;
jvm.put_static_field("java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;", value).await?;

jvm.put_static_field(
"java/lang/Boolean",
"TYPE",
"Ljava/lang/Class;",
JavaLangClass::from_rust_primitive(jvm, "boolean").await?,
)
.await
}

async fn init(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef<Self>, value: bool) -> Result<()> {
let _: () = jvm.invoke_special(&this, "java/lang/Object", "<init>", "()V", ()).await?;
jvm.put_field(&mut this, "value", "Z", value).await
}

async fn init_string(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef<Self>, value: ClassInstanceRef<String>) -> Result<()> {
let parsed = if value.is_null() {
false
} else {
JavaLangString::to_rust_string(jvm, &value).await?.eq_ignore_ascii_case("true")
};

let _: () = jvm.invoke_special(&this, "java/lang/Object", "<init>", "()V", ()).await?;
jvm.put_field(&mut this, "value", "Z", parsed).await
}

async fn boolean_value(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<bool> {
jvm.get_field(&this, "value", "Z").await
}

async fn value_of_string(jvm: &Jvm, _: &mut RuntimeContext, value: ClassInstanceRef<String>) -> Result<ClassInstanceRef<Self>> {
let parsed = if value.is_null() {
false
} else {
JavaLangString::to_rust_string(jvm, &value).await?.eq_ignore_ascii_case("true")
};

if parsed {
jvm.get_static_field("java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;").await
} else {
jvm.get_static_field("java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;").await
}
}

async fn to_string(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>) -> Result<ClassInstanceRef<String>> {
let value: bool = jvm.invoke_virtual(&this, "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<Self>) -> Result<i32> {
let value: bool = jvm.invoke_virtual(&this, "booleanValue", "()Z", ()).await?;
Ok(if value { 1231 } else { 1237 })
}

async fn equals(jvm: &Jvm, _: &mut RuntimeContext, this: ClassInstanceRef<Self>, other: ClassInstanceRef<Object>) -> Result<bool> {
if other.is_null() || !jvm.is_instance(&**other, "java/lang/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?;
Ok(this_value == other_value)
}

async fn get_boolean(jvm: &Jvm, _: &mut RuntimeContext, name: ClassInstanceRef<String>) -> Result<bool> {
if name.is_null() {
return Ok(false);
}

let value: ClassInstanceRef<String> = jvm
.invoke_static("java/lang/System", "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", (name,))
.await?;
if value.is_null() {
return Ok(false);
}

Ok(JavaLangString::to_rust_string(jvm, &value).await?.eq_ignore_ascii_case("true"))
}
}
Loading