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
4 changes: 2 additions & 2 deletions ristretto_vm/src/instruction/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,9 @@ mod tests {

#[tokio::test]
async fn test_arraylength_invalid_type() -> Result<()> {
let (vm, _thread, _frame) = crate::test::frame().await?;
let (_vm, thread) = crate::test::thread().await?;
let stack = &mut OperandStack::with_max_size(1);
let invalid_value = "foo".to_object(&vm).await?;
let invalid_value = "foo".to_object(&thread).await?;
stack.push(invalid_value)?;
let result = arraylength(stack);
assert!(matches!(
Expand Down
37 changes: 18 additions & 19 deletions ristretto_vm/src/instruction/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ pub(crate) fn ifnonnull(stack: &mut OperandStack, address: u16) -> Result<Execut
#[cfg(test)]
mod test {
use super::*;
use crate::VM;
use crate::java_object::JavaObject;
use ristretto_classloader::Reference;

Expand Down Expand Up @@ -587,10 +586,10 @@ mod test {

#[tokio::test]
async fn test_if_acmpeq_class_equal() -> Result<()> {
let vm = VM::default().await?;
let class = vm.class("java.lang.String").await?;
let class1 = class.to_object(&vm).await?;
let class2 = class.to_object(&vm).await?;
let (_vm, thread) = crate::test::thread().await?;
let class = thread.class("java.lang.String").await?;
let class1 = class.to_object(&thread).await?;
let class2 = class.to_object(&thread).await?;

let stack = &mut OperandStack::with_max_size(2);
stack.push_object(Some(class1.try_into()?))?;
Expand All @@ -602,11 +601,11 @@ mod test {

#[tokio::test]
async fn test_if_acmpeq_class_not_equal() -> Result<()> {
let vm = VM::default().await?;
let class1 = vm.class("java.lang.Object").await?;
let class1 = class1.to_object(&vm).await?;
let class2 = vm.class("java.lang.String").await?;
let class2 = class2.to_object(&vm).await?;
let (_vm, thread) = crate::test::thread().await?;
let class1 = thread.class("java.lang.Object").await?;
let class1 = class1.to_object(&thread).await?;
let class2 = thread.class("java.lang.String").await?;
let class2 = class2.to_object(&thread).await?;

let stack = &mut OperandStack::with_max_size(2);
stack.push_object(Some(class1.try_into()?))?;
Expand Down Expand Up @@ -650,10 +649,10 @@ mod test {

#[tokio::test]
async fn test_if_acmpne_class_equal() -> Result<()> {
let vm = VM::default().await?;
let class = vm.class("java.lang.String").await?;
let class1 = class.to_object(&vm).await?;
let class2 = class.to_object(&vm).await?;
let (_vm, thread) = crate::test::thread().await?;
let class = thread.class("java.lang.String").await?;
let class1 = class.to_object(&thread).await?;
let class2 = class.to_object(&thread).await?;

let stack = &mut OperandStack::with_max_size(2);
stack.push_object(Some(class1.try_into()?))?;
Expand All @@ -665,11 +664,11 @@ mod test {

#[tokio::test]
async fn test_if_acmpne_class_not_equal() -> Result<()> {
let vm = VM::default().await?;
let class1 = vm.class("java.lang.Object").await?;
let class1 = class1.to_object(&vm).await?;
let class2 = vm.class("java.lang.String").await?;
let class2 = class2.to_object(&vm).await?;
let (_vm, thread) = crate::test::thread().await?;
let class1 = thread.class("java.lang.Object").await?;
let class1 = class1.to_object(&thread).await?;
let class2 = thread.class("java.lang.String").await?;
let class2 = class2.to_object(&thread).await?;

let stack = &mut OperandStack::with_max_size(2);
stack.push_object(Some(class1.try_into()?))?;
Expand Down
7 changes: 3 additions & 4 deletions ristretto_vm/src/instruction/exception.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,13 @@ pub(crate) async fn convert_error_to_throwable(vm: Arc<VM>, error: Error) -> Res
#[cfg(test)]
mod test {
use super::*;
use crate::VM;
use crate::java_object::JavaObject;

#[tokio::test]
async fn test_process_throwable() -> Result<()> {
let vm = VM::default().await?;
let value = "foo".to_object(&vm).await?;
let result = vm
let (_vm, thread) = crate::test::thread().await?;
let value = "foo".to_object(&thread).await?;
let result = thread
.invoke(
"java.lang.Integer",
"parseInt(Ljava/lang/String;)I",
Expand Down
40 changes: 18 additions & 22 deletions ristretto_vm/src/instruction/invokedynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
use crate::frame::{ExecutionResult, Frame};
use crate::operand_stack::OperandStack;
use crate::thread::Thread;
use crate::{JavaObject, Result, VM};
use crate::{JavaObject, Result};
use ristretto_classfile::attributes::{Attribute, BootstrapMethod};
use ristretto_classfile::{Constant, ConstantPool, FieldType, MethodAccessFlags, ReferenceKind};
use ristretto_classloader::{Class, ConcurrentVec, Method, ObjectArray, Reference, Value};
Expand Down Expand Up @@ -291,18 +291,14 @@
/// that represents that type in the JVM. For primitive types and arrays, this returns the
/// corresponding class objects (like `java.lang.Integer.TYPE` for `int`). For reference types, it
/// loads the class for the specified type.
async fn get_field_type_class(
vm: &VM,
thread: &Thread,
field_type: Option<FieldType>,
) -> Result<Value> {
async fn get_field_type_class(thread: &Thread, field_type: Option<FieldType>) -> Result<Value> {

Check warning on line 294 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L294

Added line #L294 was not covered by tests
let class_name = if let Some(field_type) = field_type {
field_type.class_name()
} else {
"void".to_string()
};
let class = thread.class(class_name).await?;
class.to_object(vm).await
class.to_object(thread).await

Check warning on line 301 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L301

Added line #L301 was not covered by tests
}

/// **Step 3.2** Create MethodType from method descriptor:
Expand All @@ -315,9 +311,9 @@
/// This function parses the provided method descriptor into its constituent parts (argument types
/// and return type), creates `Class` objects for each type, and then invokes the appropriate
/// `MethodType.methodType()` factory method to create a `MethodType` instance.
async fn get_method_type(vm: &VM, thread: &Thread, method_descriptor: &str) -> Result<Value> {
async fn get_method_type(thread: &Thread, method_descriptor: &str) -> Result<Value> {

Check warning on line 314 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L314

Added line #L314 was not covered by tests
let (argument_types, return_type) = FieldType::parse_method_descriptor(method_descriptor)?;
let return_class = get_field_type_class(vm, thread, return_type).await?;
let return_class = get_field_type_class(thread, return_type).await?;

Check warning on line 316 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L316

Added line #L316 was not covered by tests

let method_type_class = thread.class("java.lang.invoke.MethodType").await?;
if argument_types.is_empty() {
Expand All @@ -330,10 +326,10 @@
.await;
}

let first_argument = get_field_type_class(vm, thread, argument_types.first().cloned()).await?;
let first_argument = get_field_type_class(thread, argument_types.first().cloned()).await?;

Check warning on line 329 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L329

Added line #L329 was not covered by tests
let argument_classes = ConcurrentVec::from(Vec::with_capacity(argument_types.len() - 1));
for argument_type in argument_types.iter().skip(1) {
let argument_class = get_field_type_class(vm, thread, Some(argument_type.clone())).await?;
let argument_class = get_field_type_class(thread, Some(argument_type.clone())).await?;

Check warning on line 332 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L332

Added line #L332 was not covered by tests
let argument_reference: Reference = argument_class.try_into()?;
argument_classes.push(Some(argument_reference))?;
}
Expand All @@ -360,17 +356,17 @@
///
/// This function obtains a lookup object that has the access privileges of the caller's class. The
/// lookup object is used for finding and binding methods during dynamic method invocation.
async fn resolve_method_handle(vm: &VM, thread: &Thread, frame: &Frame) -> Result<Value> {
async fn resolve_method_handle(thread: &Thread, frame: &Frame) -> Result<Value> {

Check warning on line 359 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L359

Added line #L359 was not covered by tests
let lookup = resolve_method_handles_lookup(thread).await?;

// Get the caller MethodHandle
let class = frame.class();
let class_object = class.to_object(vm).await?;
let class_object = class.to_object(thread).await?;

Check warning on line 364 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L364

Added line #L364 was not covered by tests
let method = frame.method();
let method_name = method.name();
let method_name_object = method_name.to_object(vm).await?;
let method_name_object = method_name.to_object(thread).await?;

Check warning on line 367 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L367

Added line #L367 was not covered by tests
let method_descriptor = method.descriptor();
let method_type = get_method_type(vm, thread, method_descriptor).await?;
let method_type = get_method_type(thread, method_descriptor).await?;

Check warning on line 369 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L369

Added line #L369 was not covered by tests
let mut arguments = vec![method_name_object, method_type];

let lookup_class = thread
Expand Down Expand Up @@ -421,7 +417,7 @@
/// in the constant pool. This function resolves those arguments from the constant pool and creates
/// arguments vector.
async fn resolve_static_bootstrap_arguments(
vm: &Arc<VM>,
thread: &Arc<Thread>,

Check warning on line 420 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L420

Added line #L420 was not covered by tests
constant_pool: &ConstantPool,
bootstrap_method: &BootstrapMethod,
) -> Result<Vec<Value>> {
Expand All @@ -443,7 +439,7 @@
}
Constant::String(value) => {
let string = constant_pool.try_get_utf8(*value)?;
let value = string.to_object(vm).await?;
let value = string.to_object(thread).await?;

Check warning on line 442 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L442

Added line #L442 was not covered by tests
arguments.push(value);
}
_ => {
Expand Down Expand Up @@ -511,12 +507,12 @@
);

// Invoke the bootstrap method
let vm = thread.vm()?;
let method_handle = resolve_method_handle(&vm, &thread, frame).await?;
let method_handle = resolve_method_handle(&thread, frame).await?;

Check warning on line 510 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L510

Added line #L510 was not covered by tests
let static_arguments =
resolve_static_bootstrap_arguments(&vm, constant_pool, &bootstrap_method_attribute).await?;
let method_name = bootstrap_method_attr_name.to_object(&vm).await?;
let method_type = get_method_type(&vm, &thread, bootstrap_method_descriptor).await?;
resolve_static_bootstrap_arguments(&thread, constant_pool, &bootstrap_method_attribute)
.await?;
let method_name = bootstrap_method_attr_name.to_object(&thread).await?;
let method_type = get_method_type(&thread, bootstrap_method_descriptor).await?;

Check warning on line 515 in ristretto_vm/src/instruction/invokedynamic.rs

View check run for this annotation

Codecov / codecov/patch

ristretto_vm/src/instruction/invokedynamic.rs#L512-L515

Added lines #L512 - L515 were not covered by tests

// 4.1 Construct argument array for bootstrap method:
let mut arguments = vec![method_handle, method_name, method_type];
Expand Down
6 changes: 2 additions & 4 deletions ristretto_vm/src/instruction/ldc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,13 @@ async fn load_constant(
Constant::String(utf8_index) => {
let utf8_value = constant_pool.try_get_utf8(*utf8_index)?;
let thread = frame.thread()?;
let vm = thread.vm()?;
utf8_value.to_object(&vm).await?
utf8_value.to_object(&thread).await?
}
Constant::Class(class_index) => {
let class_name = constant_pool.try_get_utf8(*class_index)?;
let thread = frame.thread()?;
let vm = thread.vm()?;
let class = thread.class(class_name).await?;
class.to_object(&vm).await?
class.to_object(&thread).await?
}
constant => {
return Err(InvalidConstant {
Expand Down
8 changes: 4 additions & 4 deletions ristretto_vm/src/instruction/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,9 +641,9 @@ mod tests {

#[tokio::test]
async fn test_checkcast_string_to_object() -> Result<()> {
let (vm, _thread, mut frame) = crate::test::frame().await?;
let (_vm, thread, mut frame) = crate::test::frame().await?;
let stack = &mut OperandStack::with_max_size(1);
let string = "foo".to_object(&vm).await?;
let string = "foo".to_object(&thread).await?;
stack.push(string)?;
let class_index = get_class_index(&mut frame, "java/lang/Object")?;
let result = checkcast(&frame, stack, class_index).await?;
Expand Down Expand Up @@ -695,9 +695,9 @@ mod tests {

#[tokio::test]
async fn test_instanceof_string_to_object() -> Result<()> {
let (vm, _thread, mut frame) = crate::test::frame().await?;
let (_vm, thread, mut frame) = crate::test::frame().await?;
let stack = &mut OperandStack::with_max_size(1);
let string = "foo".to_object(&vm).await?;
let string = "foo".to_object(&thread).await?;
stack.push(string)?;
let class_index = get_class_index(&mut frame, "java/lang/Object")?;
let result = instanceof(&frame, stack, class_index).await?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ mod tests {

#[tokio::test]
async fn test_has_static_initializer_false() -> Result<()> {
let (vm, thread) = crate::test::thread().await.expect("thread");
let (_vm, thread) = crate::test::thread().await.expect("thread");
let class = thread.class("java/lang/Object").await?;
let class_object = class.to_object(&vm).await?;
let class_object = class.to_object(&thread).await?;
let mut parameters = Parameters::default();
parameters.push(class_object);
let has_initializer = has_static_initializer(thread, parameters).await?;
Expand All @@ -51,9 +51,9 @@ mod tests {

#[tokio::test]
async fn test_has_static_initializer_true() -> Result<()> {
let (vm, thread) = crate::test::thread().await.expect("thread");
let (_vm, thread) = crate::test::thread().await.expect("thread");
let class = thread.class("java/lang/System").await?;
let class_object = class.to_object(&vm).await?;
let class_object = class.to_object(&thread).await?;
let mut parameters = Parameters::default();
parameters.push(class_object);
let has_initializer = has_static_initializer(thread, parameters).await?;
Expand Down
Loading
Loading