AndLong, IntModulo, ASHRLong and native methods
This commit is contained in:
parent
8e5b6bb2b8
commit
796e52241d
3 changed files with 336 additions and 7 deletions
|
@ -108,8 +108,10 @@ impl Bytecode {
|
||||||
0x78 => (Instruction::ArithmeticShiftIntLeft(), 1),
|
0x78 => (Instruction::ArithmeticShiftIntLeft(), 1),
|
||||||
0x79 => (Instruction::ArithmeticShiftLongLeft(), 1),
|
0x79 => (Instruction::ArithmeticShiftLongLeft(), 1),
|
||||||
0x7A => (Instruction::ArithmeticShiftIntRight(), 1),
|
0x7A => (Instruction::ArithmeticShiftIntRight(), 1),
|
||||||
|
0x7B => (Instruction::ArithmeticShiftLongRight(), 1),
|
||||||
0x7C => (Instruction::LogicalShiftIntRight(), 1),
|
0x7C => (Instruction::LogicalShiftIntRight(), 1),
|
||||||
0x7E => (Instruction::AndInt(), 1),
|
0x7E => (Instruction::AndInt(), 1),
|
||||||
|
0x7F => (Instruction::AndLong(), 1),
|
||||||
|
|
||||||
0x80 => (Instruction::OrInt(), 1),
|
0x80 => (Instruction::OrInt(), 1),
|
||||||
0x82 => (Instruction::XorInt(), 1),
|
0x82 => (Instruction::XorInt(), 1),
|
||||||
|
@ -393,8 +395,10 @@ pub enum Instruction {
|
||||||
ArithmeticShiftIntLeft() = 0x78, // shift int left, preserve sign
|
ArithmeticShiftIntLeft() = 0x78, // shift int left, preserve sign
|
||||||
ArithmeticShiftLongLeft() = 0x79, // shift long left, preserve sign
|
ArithmeticShiftLongLeft() = 0x79, // shift long left, preserve sign
|
||||||
ArithmeticShiftIntRight() = 0x7A, // shift int right, preserve sign
|
ArithmeticShiftIntRight() = 0x7A, // shift int right, preserve sign
|
||||||
|
ArithmeticShiftLongRight() = 0x7B, // shift long right, preserve sign
|
||||||
LogicalShiftIntRight() = 0x7C, // shift int right with zero extension
|
LogicalShiftIntRight() = 0x7C, // shift int right with zero extension
|
||||||
AndInt() = 0x7E, // bitwise and
|
AndInt() = 0x7E, // bitwise and
|
||||||
|
AndLong() = 0x7F, // bitwise and
|
||||||
|
|
||||||
OrInt() = 0x80, // value, value => or
|
OrInt() = 0x80, // value, value => or
|
||||||
XorInt() = 0x82, // value, value => xor
|
XorInt() = 0x82, // value, value => xor
|
||||||
|
|
34
src/jvm.rs
34
src/jvm.rs
|
@ -786,6 +786,14 @@ impl JVM {
|
||||||
wrap_stackframe_error(class, method, frame.operand_stack.push_long(long << shift))?;
|
wrap_stackframe_error(class, method, frame.operand_stack.push_long(long << shift))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Instruction::ArithmeticShiftLongRight() => {
|
||||||
|
let shift = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? as u8 % 64;
|
||||||
|
let long = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||||
|
|
||||||
|
// rust does arithmetic shift on signed values
|
||||||
|
wrap_stackframe_error(class, method, frame.operand_stack.push_long(long >> shift))?;
|
||||||
|
}
|
||||||
|
|
||||||
Instruction::ArrayLength() => {
|
Instruction::ArrayLength() => {
|
||||||
let array_reference = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
|
let array_reference = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
|
||||||
|
|
||||||
|
@ -810,6 +818,13 @@ impl JVM {
|
||||||
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(value_1 & value_2)))?;
|
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(value_1 & value_2)))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Instruction::AndLong() => {
|
||||||
|
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||||
|
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||||
|
|
||||||
|
wrap_stackframe_error(class, method, frame.operand_stack.push_long(value_1 & value_2))?;
|
||||||
|
}
|
||||||
|
|
||||||
Instruction::BranchAlways(branch_offset) => {
|
Instruction::BranchAlways(branch_offset) => {
|
||||||
frame.instruction_pointer -= offset as u32;
|
frame.instruction_pointer -= offset as u32;
|
||||||
frame.instruction_pointer = if branch_offset < 0 { frame.instruction_pointer - branch_offset.abs() as u32} else { frame.instruction_pointer + branch_offset.abs() as u32};
|
frame.instruction_pointer = if branch_offset < 0 { frame.instruction_pointer - branch_offset.abs() as u32} else { frame.instruction_pointer + branch_offset.abs() as u32};
|
||||||
|
@ -1837,9 +1852,20 @@ impl JVM {
|
||||||
let factor_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
let factor_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||||
let factor_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
let factor_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long(0))?;
|
||||||
|
|
||||||
let result = factor_1 * factor_2;
|
let (result, overflowed) = i64::overflowing_mul(factor_1, factor_2);
|
||||||
|
let java_result = if overflowed {
|
||||||
|
if result < 0 && ((factor_1 >= 0 && factor_2 <= 0 ) || (factor_1 < 0 && factor_2 >= 0)) {
|
||||||
|
result.abs()
|
||||||
|
} else if factor_1 < 0 && factor_2 < 0 {
|
||||||
|
if result < 0 { result } else { -result }
|
||||||
|
} else {
|
||||||
|
-result.abs()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result
|
||||||
|
};
|
||||||
|
|
||||||
wrap_stackframe_error(class, method, frame.operand_stack.push_long(result))?;
|
wrap_stackframe_error(class, method, frame.operand_stack.push_long(java_result))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction::ModuloInt() => {
|
Instruction::ModuloInt() => {
|
||||||
|
@ -2282,8 +2308,8 @@ impl JVM {
|
||||||
let _ = wrap_stackframe_error(class, method, frame.operand_stack.pop_long1(0))?;
|
let _ = wrap_stackframe_error(class, method, frame.operand_stack.pop_long1(0))?;
|
||||||
let long0 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long0(0))?;
|
let long0 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long0(0))?;
|
||||||
|
|
||||||
wrap_stackframe_error(class, method, frame.store_local(1, StackValue::Long0(long0)))?;
|
wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Long0(long0)))?;
|
||||||
wrap_stackframe_error(class, method, frame.store_local(2, StackValue::Long1()))?;
|
wrap_stackframe_error(class, method, frame.store_local(1, StackValue::Long1()))?;
|
||||||
}
|
}
|
||||||
Instruction::StoreLocalLong1() => {
|
Instruction::StoreLocalLong1() => {
|
||||||
let _ = wrap_stackframe_error(class, method, frame.operand_stack.pop_long1(0))?;
|
let _ = wrap_stackframe_error(class, method, frame.operand_stack.pop_long1(0))?;
|
||||||
|
|
|
@ -461,9 +461,22 @@ impl JavaLangThrowable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct JavaSecurityAccessController {}
|
||||||
|
|
||||||
|
impl JavaSecurityAccessController {
|
||||||
|
fn get_stack_access_control_context(_jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||||
|
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(ObjectReference::NULL)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct JdkInternalMiscCDS {}
|
struct JdkInternalMiscCDS {}
|
||||||
|
|
||||||
impl JdkInternalMiscCDS {
|
impl JdkInternalMiscCDS {
|
||||||
|
fn get_random_seed_for_dumping(_jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||||
|
return Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Long(42))); // TODO: Random seed
|
||||||
|
// depending on JVM
|
||||||
|
// version
|
||||||
|
}
|
||||||
fn get_cds_config_status(_jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
fn get_cds_config_status(_jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||||
return Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(0)));
|
return Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(0)));
|
||||||
}
|
}
|
||||||
|
@ -708,12 +721,24 @@ impl JdkInternalMiscUnsafe {
|
||||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(index_scale)))
|
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(index_scale)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn array_base_offset_0(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
pub fn array_base_offset_0(_jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||||
// TODO: Check passed class
|
// TODO: Check passed class
|
||||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(0)))
|
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(0)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct JdkInternalReflectReflection {}
|
||||||
|
|
||||||
|
impl JdkInternalReflectReflection {
|
||||||
|
pub fn get_caller_class(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||||
|
let caller_frame = &jvm.stack_frames[jvm.stack_frames.len() - 2];
|
||||||
|
let caller_class_index = caller_frame.class_index;
|
||||||
|
let caller_class_reference = jvm.class_store.get_class_objectref_from_index(caller_class_index);
|
||||||
|
|
||||||
|
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(caller_class_reference)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct JdkInternalUtilSystemPropsRaw {}
|
pub struct JdkInternalUtilSystemPropsRaw {}
|
||||||
|
|
||||||
impl JdkInternalUtilSystemPropsRaw {
|
impl JdkInternalUtilSystemPropsRaw {
|
||||||
|
@ -3110,7 +3135,7 @@ pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Resul
|
||||||
]),
|
]),
|
||||||
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Long() },
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Long() },
|
||||||
},
|
},
|
||||||
todo_call
|
JdkInternalMiscCDS::get_random_seed_for_dumping
|
||||||
),
|
),
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -3136,6 +3161,280 @@ pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Resul
|
||||||
},
|
},
|
||||||
todo_call
|
todo_call
|
||||||
),
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"jdk/internal/reflect/Reflection",
|
||||||
|
"getCallerClass",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) },
|
||||||
|
},
|
||||||
|
JdkInternalReflectReflection::get_caller_class
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"jdk/internal/reflect/Reflection",
|
||||||
|
"getClassAccessFlags",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"jdk/internal/reflect/Reflection",
|
||||||
|
"areNestMates",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean() },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/security/AccessController",
|
||||||
|
"getProtectionDomain",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/security/ProtectionDomain".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/security/AccessController",
|
||||||
|
"ensureMaterializedForStackWalk",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Object".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Void() },
|
||||||
|
},
|
||||||
|
ignore_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/security/AccessController",
|
||||||
|
"getStackAccessControlContext",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/security/AccessControlContext".to_string()) },
|
||||||
|
},
|
||||||
|
JavaSecurityAccessController::get_stack_access_control_context
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/security/AccessController",
|
||||||
|
"getInheritedAccessControlContext",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/security/AccessControlContext".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ref/Reference",
|
||||||
|
"getAndClearReferencePendingList",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/ref/Reference".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ref/Reference",
|
||||||
|
"hasReferencePendingList",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean() },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ref/Reference",
|
||||||
|
"waitForReferencePendingList",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Void() },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ref/Reference",
|
||||||
|
"refersTo0",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Object".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean() },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ref/Reference",
|
||||||
|
"clear0",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Void() },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ClassLoader",
|
||||||
|
"registerNatives",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Void() },
|
||||||
|
},
|
||||||
|
ignore_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ClassLoader",
|
||||||
|
"defineClass0",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/ClassLoader".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Byte() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/security/ProtectionDomain".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Object".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ClassLoader",
|
||||||
|
"defineClass1",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/ClassLoader".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Byte() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/security/ProtectionDomain".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ClassLoader",
|
||||||
|
"defineClass2",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/ClassLoader".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/nio/ByteBuffer".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() },
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/security/ProtectionDomain".to_string())},
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ClassLoader",
|
||||||
|
"findBootstrapClass",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ClassLoader",
|
||||||
|
"findLoadedClass0",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string())},
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/ClassLoader",
|
||||||
|
"retrieveDirectives",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/AssertionStatusDirectives".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/reflect/Executable",
|
||||||
|
"getParameters0",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/reflect/Parameter".to_string()) },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/reflect/Executable",
|
||||||
|
"getTypeAnnotationBytes0",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Byte() },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
|
|
||||||
|
(
|
||||||
|
"java/lang/reflect/Field",
|
||||||
|
"getTypeAnnotationBytes0",
|
||||||
|
MethodDescriptor {
|
||||||
|
argument_types: Box::new([
|
||||||
|
]),
|
||||||
|
return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Byte() },
|
||||||
|
},
|
||||||
|
todo_call
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (classname, methodname, methoddescriptor, binding) in native_mappings {
|
for (classname, methodname, methoddescriptor, binding) in native_mappings {
|
||||||
|
@ -3143,7 +3442,7 @@ pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Resul
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if methoddescriptor != m.descriptor {
|
if methoddescriptor != m.descriptor {
|
||||||
return Err(Error::RunTimeError(format!("Descriptor mismatch in native method resolution: internal is {} but classfile wants {}", methoddescriptor.source_string(), m.descriptor.source_string())));
|
return Err(Error::RunTimeError(format!("Descriptor mismatch in native method resolution for {class_name}.{method_name}: internal is {} but classfile wants {}", methoddescriptor.source_string(), m.descriptor.source_string())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(binding);
|
return Ok(binding);
|
||||||
|
|
Loading…
Reference in a new issue