Skip to content

Commit 79914a6

Browse files
committed
runtime/native: set annotation fields for java.lang.reflect.Method
1 parent 9837e89 commit 79914a6

File tree

5 files changed

+186
-30
lines changed

5 files changed

+186
-30
lines changed

classfile/src/attribute/mod.rs

Lines changed: 126 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod resolved;
22

3+
use common::box_slice;
34
use common::int_types::{u1, u2};
45

56
macro_rules! attribute_getter_methods {
@@ -304,6 +305,24 @@ pub struct RuntimeVisibleAnnotations {
304305
pub annotations: Vec<Annotation>,
305306
}
306307

308+
fn encode_annotations(annotations: &[Annotation]) -> Box<[u1]> {
309+
let num_annotations = annotations.len() as u2;
310+
let mut ret = Vec::with_capacity((num_annotations as usize) * size_of::<Annotation>());
311+
ret.extend(num_annotations.to_be_bytes());
312+
313+
for annotation in annotations {
314+
ret.extend(annotation.as_bytes());
315+
}
316+
317+
ret.into_boxed_slice()
318+
}
319+
320+
impl RuntimeVisibleAnnotations {
321+
pub fn as_bytes(&self) -> Box<[u1]> {
322+
encode_annotations(self.annotations.as_slice())
323+
}
324+
}
325+
307326
#[repr(transparent)]
308327
#[derive(Debug, Clone, PartialEq, Default)]
309328
pub struct RuntimeInvisibleAnnotations {
@@ -316,6 +335,12 @@ pub struct RuntimeVisibleParameterAnnotations {
316335
pub annotations: Vec<Annotation>,
317336
}
318337

338+
impl RuntimeVisibleParameterAnnotations {
339+
pub fn as_bytes(&self) -> Box<[u1]> {
340+
encode_annotations(self.annotations.as_slice())
341+
}
342+
}
343+
319344
#[repr(transparent)]
320345
#[derive(Debug, Clone, PartialEq, Default)]
321346
pub struct RuntimeInvisibleParameterAnnotations {
@@ -328,6 +353,12 @@ pub struct RuntimeVisibleTypeAnnotations {
328353
pub annotations: Vec<Annotation>,
329354
}
330355

356+
impl RuntimeVisibleTypeAnnotations {
357+
pub fn as_bytes(&self) -> Box<[u1]> {
358+
encode_annotations(self.annotations.as_slice())
359+
}
360+
}
361+
331362
#[repr(transparent)]
332363
#[derive(Debug, Clone, PartialEq, Default)]
333364
pub struct RuntimeInvisibleTypeAnnotations {
@@ -340,6 +371,12 @@ pub struct AnnotationDefault {
340371
pub default_value: ElementValue,
341372
}
342373

374+
impl AnnotationDefault {
375+
pub fn as_bytes(&self) -> Box<[u1]> {
376+
self.default_value.as_bytes()
377+
}
378+
}
379+
343380
#[repr(transparent)]
344381
#[derive(Debug, Clone, PartialEq, Default)]
345382
pub struct BootstrapMethods {
@@ -506,36 +543,70 @@ pub struct Annotation {
506543
pub element_value_pairs: Vec<ElementValuePair>,
507544
}
508545

546+
impl Annotation {
547+
pub fn as_bytes(&self) -> Box<[u1]> {
548+
let mut ret = Vec::with_capacity(size_of::<Self>() + size_of::<u2>());
549+
ret.extend(self.type_index.to_be_bytes());
550+
ret.extend((self.element_value_pairs.len() as u2).to_be_bytes());
551+
552+
for element_value_pair in &self.element_value_pairs {
553+
ret.extend(element_value_pair.as_bytes());
554+
}
555+
556+
ret.into_boxed_slice()
557+
}
558+
}
559+
509560
// https://docs.oracle.com/javase/specs/jvms/se23/html/jvms-4.html#jvms-4.7.16
510561
#[derive(Debug, Clone, PartialEq)]
511562
pub struct ElementValuePair {
512563
pub element_name_index: u2,
513564
pub value: ElementValue,
514565
}
515566

567+
impl ElementValuePair {
568+
pub fn as_bytes(&self) -> Box<[u1]> {
569+
let mut ret = Vec::with_capacity(size_of::<Self>());
570+
ret.extend(self.element_name_index.to_be_bytes());
571+
ret.extend(self.value.as_bytes());
572+
ret.into_boxed_slice()
573+
}
574+
}
575+
516576
// https://docs.oracle.com/javase/specs/jvms/se23/html/jvms-4.html#jvms-4.7.16.1
517577
#[derive(Debug, Clone, PartialEq)]
518578
pub struct ElementValue {
519579
pub tag: ElementValueTag,
520580
pub ty: ElementValueType,
521581
}
522582

583+
impl ElementValue {
584+
pub fn as_bytes(&self) -> Box<[u1]> {
585+
let mut ret =
586+
Vec::with_capacity(size_of::<ElementValueTag>() + size_of::<ElementValueType>());
587+
ret.push(self.tag as u8);
588+
ret.extend(self.ty.as_bytes());
589+
ret.into_boxed_slice()
590+
}
591+
}
592+
523593
// https://docs.oracle.com/javase/specs/jvms/se23/html/jvms-4.html#jvms-4.7.16.1
594+
#[repr(u8)]
524595
#[derive(Debug, Copy, Clone, PartialEq)]
525596
pub enum ElementValueTag {
526-
Byte,
527-
Char,
528-
Double,
529-
Float,
530-
Int,
531-
Long,
532-
Short,
533-
Boolean,
534-
String,
535-
Enum,
536-
Class,
537-
Annotation,
538-
Array,
597+
Byte = b'B',
598+
Char = b'C',
599+
Double = b'D',
600+
Float = b'F',
601+
Int = b'I',
602+
Long = b'J',
603+
Short = b'S',
604+
Boolean = b'Z',
605+
String = b's',
606+
Enum = b'e',
607+
Class = b'c',
608+
Annotation = b'@',
609+
Array = b'[',
539610
}
540611

541612
impl From<u1> for ElementValueTag {
@@ -587,6 +658,48 @@ pub enum ElementValueType {
587658
},
588659
}
589660

661+
impl ElementValueType {
662+
pub fn as_bytes(&self) -> Box<[u1]> {
663+
match self {
664+
ElementValueType::Byte { const_value_index }
665+
| ElementValueType::Char { const_value_index }
666+
| ElementValueType::Double { const_value_index }
667+
| ElementValueType::Float { const_value_index }
668+
| ElementValueType::Int { const_value_index }
669+
| ElementValueType::Long { const_value_index }
670+
| ElementValueType::Short { const_value_index }
671+
| ElementValueType::Boolean { const_value_index }
672+
| ElementValueType::String { const_value_index } => {
673+
let [b1, b2] = const_value_index.to_be_bytes();
674+
box_slice![b1, b2]
675+
},
676+
ElementValueType::Enum {
677+
type_name_index,
678+
const_value_index,
679+
} => {
680+
let [b1, b2] = type_name_index.to_be_bytes();
681+
let [b3, b4] = const_value_index.to_be_bytes();
682+
box_slice![b1, b2, b3, b4]
683+
},
684+
ElementValueType::Class { class_info_index } => {
685+
let [b1, b2] = class_info_index.to_be_bytes();
686+
box_slice![b1, b2]
687+
},
688+
ElementValueType::Annotation { annotation } => annotation.as_bytes(),
689+
ElementValueType::Array { values } => {
690+
let mut ret = Vec::with_capacity(values.len() * size_of::<ElementValue>());
691+
ret.extend((values.len() as u2).to_be_bytes());
692+
693+
for value in values {
694+
ret.extend(value.as_bytes());
695+
}
696+
697+
ret.into_boxed_slice()
698+
},
699+
}
700+
}
701+
}
702+
590703
// https://docs.oracle.com/javase/specs/jvms/se23/html/jvms-4.html#jvms-4.7.23
591704
#[derive(Debug, Clone, PartialEq)]
592705
pub struct BootstrapMethod {

common/src/array.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use crate::int_types::{s1, u1};
2+
3+
pub trait IntoJByte {
4+
fn into_jbyte_array(self) -> Box<[s1]>;
5+
}
6+
7+
impl IntoJByte for Box<[u1]> {
8+
fn into_jbyte_array(self) -> Box<[s1]> {
9+
let ptr = Box::into_raw(self);
10+
unsafe { Box::from_raw(ptr as *mut [s1]) }
11+
}
12+
}

common/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
extern crate alloc;
22

3+
pub mod array;
34
pub mod atomic;
45
pub mod endian;
56
pub mod error;

runtime/src/classes/java/lang/reflect/Method.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::globals;
22
use crate::native::java::lang::String::StringInterner;
33
use crate::objects::instance::Instance;
4-
use crate::objects::instance::array::{ObjectArrayInstanceRef, PrimitiveArrayInstanceRef};
4+
use crate::objects::instance::array::{
5+
ObjectArrayInstanceRef, PrimitiveArrayInstance, PrimitiveArrayInstanceRef,
6+
};
57
use crate::objects::instance::class::{ClassInstance, ClassInstanceRef};
68
use crate::objects::instance::mirror::MirrorInstanceRef;
79
use crate::objects::method::Method;
@@ -35,21 +37,17 @@ pub fn new(method: &Method) -> Throws<ClassInstanceRef> {
3537
set_signature(reflect_method, StringInterner::intern(generic_signature));
3638
}
3739

38-
// // TODO
39-
// set_annotations(
40-
// constructor.get_mut(),
41-
// Reference::null(),
42-
// );
43-
// // TODO
44-
// set_parameterAnnotations(
45-
// constructor.get_mut(),
46-
// Reference::null(),
47-
// );
48-
// // TODO
49-
// set_annotationDefault(
50-
// constructor.get_mut(),
51-
// Reference::null(),
52-
// );
40+
if let Some(annotations) = method.annotations_array() {
41+
set_annotations(reflect_method, annotations);
42+
}
43+
44+
if let Some(parameter_annotations) = method.parameter_annotations_array() {
45+
set_parameterAnnotations(reflect_method, parameter_annotations);
46+
}
47+
48+
if let Some(annotation_default) = method.annotation_default() {
49+
set_annotationDefault(reflect_method, annotation_default);
50+
}
5351

5452
Throws::Ok(reflect_method)
5553
}

runtime/src/objects/method/mod.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use crate::native::method::NativeMethodPtr;
55
use crate::objects::class::ClassPtr;
66
use crate::objects::constant_pool::cp_types;
77
use crate::objects::constant_pool::cp_types::MethodEntry;
8-
use crate::objects::instance::array::{Array, ObjectArrayInstance, ObjectArrayInstanceRef};
8+
use crate::objects::instance::array::{
9+
Array, ObjectArrayInstance, ObjectArrayInstanceRef, PrimitiveArrayInstance,
10+
PrimitiveArrayInstanceRef,
11+
};
912
use crate::objects::instance::mirror::MirrorInstanceRef;
1013
use crate::objects::instance::object::Object;
1114
use crate::objects::reference::Reference;
@@ -23,6 +26,7 @@ use classfile::accessflags::MethodAccessFlags;
2326
use classfile::attribute::resolved::ResolvedAnnotation;
2427
use classfile::attribute::{Attribute, Code, LineNumber};
2528
use classfile::{FieldType, MethodDescriptor, MethodInfo};
29+
use common::array::IntoJByte;
2630
use common::int_types::{s4, u1};
2731
use instructions::Operand;
2832
use jni::sys::{jdouble, jint, jlong, jobject, jvalue};
@@ -343,6 +347,34 @@ impl Method {
343347

344348
Throws::Ok(array)
345349
}
350+
351+
pub fn annotations_array(&self) -> Option<PrimitiveArrayInstanceRef> {
352+
self.attributes
353+
.iter()
354+
.find_map(Attribute::runtime_visible_annotations)
355+
.map(|attr| PrimitiveArrayInstance::new(attr.as_bytes().into_jbyte_array()))
356+
}
357+
358+
pub fn parameter_annotations_array(&self) -> Option<PrimitiveArrayInstanceRef> {
359+
self.attributes
360+
.iter()
361+
.find_map(Attribute::runtime_visible_parameter_annotations)
362+
.map(|attr| PrimitiveArrayInstance::new(attr.as_bytes().into_jbyte_array()))
363+
}
364+
365+
pub fn type_annotations_array(&self) -> Option<PrimitiveArrayInstanceRef> {
366+
self.attributes
367+
.iter()
368+
.find_map(Attribute::runtime_visible_type_annotations)
369+
.map(|attr| PrimitiveArrayInstance::new(attr.as_bytes().into_jbyte_array()))
370+
}
371+
372+
pub fn annotation_default(&self) -> Option<PrimitiveArrayInstanceRef> {
373+
self.attributes
374+
.iter()
375+
.find_map(Attribute::annotation_default)
376+
.map(|attr| PrimitiveArrayInstance::new(attr.as_bytes().into_jbyte_array()))
377+
}
346378
}
347379

348380
// Flags

0 commit comments

Comments
 (0)