From 2f4bac0eed6ece5c15d5684690f62735b3fa789f Mon Sep 17 00:00:00 2001 From: Igor Rudenko Date: Sun, 22 Dec 2024 15:43:21 +0200 Subject: [PATCH] Add support of Class.getDeclaringClass() --- tests/integration_tests.rs | 20 +++++ tests/test_data/GetDeclaringClassExample.java | 72 ++++++++++++++++++ .../GetDeclaringClassExample$1.class | Bin 0 -> 554 bytes ...GetDeclaringClassExample$1LocalClass.class | Bin 0 -> 506 bytes ...aringClassExample$1StaticMethodInner.class | Bin 0 -> 512 bytes ...sExample$DeepNesting$Inner$DeepInner.class | Bin 0 -> 835 bytes ...laringClassExample$DeepNesting$Inner.class | Bin 0 -> 829 bytes ...GetDeclaringClassExample$DeepNesting.class | Bin 0 -> 563 bytes ...aringClassExample$SimpleNested$Inner.class | Bin 0 -> 698 bytes ...assExample$SimpleNested$StaticNested.class | Bin 0 -> 580 bytes ...etDeclaringClassExample$SimpleNested.class | Bin 0 -> 702 bytes .../GetDeclaringClassExample$TopLevel.class | Bin 0 -> 436 bytes .../GetDeclaringClassExample.class | Bin 0 -> 2806 bytes .../execution_engine/system_native_table.rs | 6 +- vm/src/method_area/attributes_helper.rs | 10 ++- vm/src/method_area/java_class.rs | 7 ++ vm/src/method_area/method_area.rs | 33 ++++++++ vm/src/system_native/class.rs | 24 ++++++ 18 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 tests/test_data/GetDeclaringClassExample.java create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$1.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$1LocalClass.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$1StaticMethodInner.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$DeepNesting$Inner$DeepInner.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$DeepNesting$Inner.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$DeepNesting.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$SimpleNested$Inner.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$SimpleNested$StaticNested.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$SimpleNested.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$TopLevel.class create mode 100644 tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample.class diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 759a8f83..0632571f 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -654,3 +654,23 @@ Interfaces implemented by int: "#, ); } + +#[test] +fn should_return_declaring_class() { + assert_success( + "samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample", + r#"double: null +[Ljava.lang.String;: null +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample: null +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$TopLevel: class samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$SimpleNested$Inner: class samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$SimpleNested +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$SimpleNested$StaticNested: class samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$SimpleNested +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$1: null +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$1LocalClass: null +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$1StaticMethodInner: null +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$DeepNesting$Inner: class samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$DeepNesting +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$DeepNesting$Inner$DeepInner: class samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$DeepNesting$Inner +samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$DeepNesting$Inner$DeepInner: class samples.reflection.trivial.classgetdeclaringclassexample.GetDeclaringClassExample$DeepNesting$Inner +"#, + ); +} diff --git a/tests/test_data/GetDeclaringClassExample.java b/tests/test_data/GetDeclaringClassExample.java new file mode 100644 index 00000000..f4a15c05 --- /dev/null +++ b/tests/test_data/GetDeclaringClassExample.java @@ -0,0 +1,72 @@ +package samples.reflection.trivial.classgetdeclaringclassexample; + +public class GetDeclaringClassExample { + public static class TopLevel { + } + + public static class SimpleNested { + public class Inner { + } + + public static class StaticNested { + } + } + + public static void main(String[] args) { + print(double.class); + + print(String[].class); + + print(GetDeclaringClassExample.class); + + print(TopLevel.class); + + print(SimpleNested.Inner.class); + + print(SimpleNested.StaticNested.class); + + Runnable anonymous = new Runnable() { + @Override + public void run() { + } + }; + print(anonymous.getClass()); + + class LocalClass { + } + print(LocalClass.class); + + testStaticMethodInner(); + + DeepNesting outer = new DeepNesting(); + DeepNesting.Inner inner = outer.new Inner(); + DeepNesting.Inner.DeepInner deepInner = inner.new DeepInner(); + print(DeepNesting.Inner.class); + print(DeepNesting.Inner.DeepInner.class); + print(deepInner.getClass()); + +// Runnable lambda = () -> { +// }; +// print(lambda.getClass()); // Execution Error: Unknown reference opcode: 186 + } + + private static void testStaticMethodInner() { + class StaticMethodInner { + } + print(StaticMethodInner.class); + } + + static class DeepNesting { + public class Inner { + public class DeepInner { + } + } + } + + private static void print(Class clazz) { + System.out.print(clazz.getName()); + System.out.print(": "); + System.out.println(clazz.getDeclaringClass()); + } + +} diff --git a/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$1.class b/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$1.class new file mode 100644 index 0000000000000000000000000000000000000000..00455785e657da0b37f1857887eb3ed15ac3ed7e GIT binary patch literal 554 zcmb_ZO;5r=5Pb`kVnz8-Q4@(CJb(uq&l)d?9|>X(1TN?1TapfZ+I=>}5!?)7j?UMx^JR$9d; z0{LcZV52C|H*)e6kZ~h=2w0;+?Z%OsDjB$5AdT@U9uZrS(thTk=PbfKr}*@nXs61~ zjMzK0;Rw{`uiqwG%V9tQRy!Oql)Fk(FPRJ}x|b3EceqcS=~pI#)iCiYu%)@4NGl^|@2pKWYsGiaj#%MQFImrAw_T z%34AOyRdmI0*gGO9B&>C-kDf0i8cTL literal 0 HcmV?d00001 diff --git a/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$1LocalClass.class b/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$1LocalClass.class new file mode 100644 index 0000000000000000000000000000000000000000..c0c0025655cc5d3c54156aa5eaed14bf4a367453 GIT binary patch literal 506 zcmb_ZO-}+b5PgM}#dQVz;znYk2k_v=v&IYJM}ioG;bJ_LWn4>2YqksVZ+SBD;1BRe z8E4lRPTp+NzUg~2&AjR7*ZT*6E}8*KDEsh2te_&$n97BWv@}U{GoDhM2~75*FW`d!er!k$Y{L=dCvBTU0m-kGpt>YH1DSNUL zA9aD-e{Vg+1~$3pnN&ug*}m^DM>yoEnB=%K5~vQyWtZ0RK*K9zC@s8_V^d4(*oDvk ykuSlUe}r+BqZVVq9K1oi7IMI6E(3e;u*O(Ih;>E}H8ikQFg0v52At#uJ|rkYMeJ^J6j!c;Vz=UNF(EPV1Nc#h ziz_Bz!;<~Z@7@~0?*LNtBGgb15yV(QL!dL23z=wXCdtisN|_UA94n*Ti9mgK z?>>go_$4fPVV$uNUO}jQrI~h zIq6h(P42PCFO8v6AV`ax1lm{1&~QE*Q+X%Hnwe-+%*%|#>B90$ zmd!)71#bV{L5yzoe?3Rm{oEvYHbS0CwFGaT3*#zBeMZmh lze2otIpVXDfg=Q1W2_;@I%9wqI@s_`3!97)=Y@=0z!%{NjFSKW literal 0 HcmV?d00001 diff --git a/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$DeepNesting$Inner$DeepInner.class b/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$DeepNesting$Inner$DeepInner.class new file mode 100644 index 0000000000000000000000000000000000000000..ef9c13a1784057aefcf5d36d5744fae2ca5dbac3 GIT binary patch literal 835 zcmcgq$xZ@65Pc=fuqorNBpggQfCuLTTrS|2AZj$+JTy?kkYR?*G{mF7rBc=P@%i=+ppH@wOGsEq7LY=kU=P()IiB+S&UI(VT}?=4~6D4Hg?k<8zTUaIBF1#N?!A#3cl_LuqgolM!ng1t3 ze(u*SY!kYFT5z@)gw*$1WaIJ%V-J?>aePQ_3R&@T;+4gV`PBX^=*7r+dDB7z$0)>- jz-Jo?EQ_;*6%>uNu_m@8{5ouGB7-eKJCbM#+68?9NuL1I literal 0 HcmV?d00001 diff --git a/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$DeepNesting$Inner.class b/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$DeepNesting$Inner.class new file mode 100644 index 0000000000000000000000000000000000000000..54d0b2c07ed45bf2c703399315e846f39cbe19e4 GIT binary patch literal 829 zcmcIi$xZ@65PiiqY|1FEBpggQfCuLTBwoNRLDXotd1#=-A;S!rX^2OE$&-l(KfsSN z)-;-M@h06#ch!4Ud0o}@`Stz*poK~v2_!9~ibx|vu*Yhy98dWp=ej@UfhJ^{uJ7s- zLbBfIS;!Iwk(x|Bj+~GmJ&ADx-_fBvca`T1JQYPF)W?W8(mpOmMtNb{aYH^5Rv+i}Cc~8|c;01vxVU15FfT kO3W7H+C8behm@P75m|z5Eq^oze0b= zycn_b5jY*U11d3*g;)vg?-Qu=To8@ literal 0 HcmV?d00001 diff --git a/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$SimpleNested$Inner.class b/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$SimpleNested$Inner.class new file mode 100644 index 0000000000000000000000000000000000000000..77a914e28538989968c1350b52100bc88478b53e GIT binary patch literal 698 zcmcIi%}xR_5dI1*i-@w~--&|>2k_uNfW`~{CWsmgN0YKUV#%^=+Cn_~N}fzS_y9hX zak|Dt58kj%Iy2ulo$1W<{p0lwKo{Fp6j1b0s=-59AehLx3=^4-!^_cxA}dfnP^q$q z0>yS`=%XSK8##SQ$b_2i682G98d|O9N+w~HNMpuiV`5FKbese9nBNFb$sTOx`bLftMuH2n_gQ=;wVaYA zZ3L==Y^EbRQI2o^Rm`62p+Ln|bCwzFV@=?C;iU-F@S5dPM*O&eods~&q0dQcDM1;k7I1*u5Hqp(TFvNhdEc3XTcPl5*@z=slN zQ-pf()?IdHzxn2enfdzu_yiDRFTe&oAB_-Av;_K7xsXvI^(4AYr<7TN)``-}o(gye zhYvp50?$UyUJ5c%MNb9$s8UC^QVS)EC@Z8f6S6t+uTpwa8|bx;h%U*V{SvYBJYN!{ zM7fM(GM4gDVx?8t5(qTnGADuFjnXup&r+)HWm>Q$NXmJY(S>qg_+RQ{*O5TmrMoJP z_0bc!TYCor;kDLO)m@SCF%WoMdzC+P;*zUlb8uyF*oV)%bw}{!?Xv7J8rB$S9=$`n i)pWqp(ZD7=e&E0mTea?@&w9X?ZFI52DSZCzqVoe@E~yg$ literal 0 HcmV?d00001 diff --git a/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$SimpleNested.class b/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$SimpleNested.class new file mode 100644 index 0000000000000000000000000000000000000000..123a8ffa8ba9c7af2ccb78c409e4ca15e09a4976 GIT binary patch literal 702 zcmcIi%}T>S5dNlVn_6RA|3&CQ=s`W07Z5M?7o;K;kHR(?%hoiJWLtbKPl5*@z=slN zR|@sut?t5n^Ud$hGM``X9{{@8siOqXM>#+RRYGf|rYcNSIt*_HBaRHAdaP4zP6*!q z!M%?f;h|9D=Y)$e=f^~1be4uD*Hf*MFiKQW4B5miTCUTfGw_Sc2rt;2&KzAEdG_Pz z^tG+n5SuN>k3=AY2HYpTfsF;c4MbfBjUaZSK!#|8svgKcV6fd+=qO>>;_b xPa>CuwH*g4hi{-)=dO#iZb*uUWx)~xtT=3-CAceg9}TQZi8awS1UCh@LEm?h(;WZ+ literal 0 HcmV?d00001 diff --git a/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$TopLevel.class b/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample$TopLevel.class new file mode 100644 index 0000000000000000000000000000000000000000..6568cbae54a2e8d5882279f7b33ebbfdb470917b GIT binary patch literal 436 zcmb_YJx{|h5PfdarVXJj>>ZF8fPwr0#1hJfR23mA1~w->B3G_c#csskVnSlz2k@g1 z7o(1B*wQ_}dv~_qeSLp?0?2R}qk|wqn4pWEz<4DanQCdu^gdrv;RJdY$|!d!5S*Mo zMd%AWTe;q7vT02(nrl>LQdg@+Nu3s2T3eD^5}#^iN}r%t-;v&syV?m^TRHs|ju+Kt zMh$6!Fsqg%Fq$bt^X)pPdLeVonfS5V)&*UwmQ4P->AW={(4Uiax0Q7fMgkB2{$YXS z&KRn_39|g)&H;`P@l4w#c=J>_4wy|m2fAnP5N}?NIkqwoBETMF2MP8)4l!noS&cBn G0R}&w4R!MX literal 0 HcmV?d00001 diff --git a/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample.class b/tests/test_data/samples/reflection/trivial/classgetdeclaringclassexample/GetDeclaringClassExample.class new file mode 100644 index 0000000000000000000000000000000000000000..0a0a4a008282772a2b2a00c23da13e8eae44838d GIT binary patch literal 2806 zcmcImYgZdZ7=8v47M7Ju%B7TIFQ#o0E-BVZOQ5zAsMU~Cf~m2#x=E&C>1H=38;<@g z`vFkS@w3Mt8`}5A9fBp75fDKf2^r2rv$Uqna0%Hf}p_#Nz zr;>bLJdh<%U|`L1Eboy(e=MFK!XSn;=mv&ibg`%1X3>@cp}oS+roecneba_*HX11% zBN){%W?&oD8@6%e0dvb)X`>vgE98ITe3F{^XxXK9yej zY{S2LGuRLa*T_tjCt~NM$MYH{1TMYm*vV0zQ%Px<68QGQ)rs!8wTwKJwuZ|B<%_>R zXDJ6}Wy6!@=rhNWbq!Yp-t|~g&NDr$6o}PuRUmiq0+)5nqJJ3Ia9zU<12^%JK%|{f zyG_S2{d5~-n)pe;*v8@=!Sxpz+gk#!d!S&(Et$42L*?}y12I)TlOCfHIA~jX`);`v zmPAjKNK08$abObbh^sPQ6ewN1u^n=PJkycHT@A|yKE^%Px*wRPXW1>#Xb6nd<&RCP zF0-zaZQ8cL?arDEuqD+Quhx=|1>9F)^r=8Gmg%W6DFq4-1gbri61Xg?oakqRjuosb z3sVC7J+?5AO*<9Lvy_P9JpiKRa~VH`$9SUQbAv4=-PI;?KNGI1Y$k4#Ks^~0tmP(m z6mk=grCDXC*uql{Ul@3XF9k;1b>FIVjYXd|tL!!tT{YhVbR8LNYsjij^PITgpYN7I z(Vh9&IvCFn;)Oup>UE_;&cL3+opDO*Za7Ln-oQ(IBcS;`$9Dd8<5`C1*%3F~GF2VT zSdPp#t3_Gg3$QCxH7%Z-iv34Ziu2%5&Z;=3*R1pObf>z$8`ct!7+3*4=Qislxn-&D zJNJLhaY;ErU|8YBwp2x$gzW(@m`YPqAq(7ZO% zQvD7nqJRFWDF*3W4&nxZxsR_LAOyY*Fu<|EuQ^gd8crNT{K5&lKS#9<^kWFG@Ezxh z^$#8mlh)otJHZE$OKKQV!=xIf)iA^16tjh6%w^_(#fJiFHOk=xw@(r0#{Bjv777c6 z6D++v#wXcRtP~boUk_J9kp*>Pg~Lqf2y3Kmt+trMz!> = Lazy::ne "java/lang/Class:getInterfaces0:()[Ljava/lang/Class;", Basic(get_interfaces0_wrp), ); + table.insert( + "java/lang/Class:getDeclaringClass0:()Ljava/lang/Class;", + Basic(get_declaring_class0_wrp), + ); table.insert( "jdk/internal/misc/Unsafe:registerNatives:()V", Basic(void_stub), diff --git a/vm/src/method_area/attributes_helper.rs b/vm/src/method_area/attributes_helper.rs index d6875488..400efa5b 100644 --- a/vm/src/method_area/attributes_helper.rs +++ b/vm/src/method_area/attributes_helper.rs @@ -1,4 +1,4 @@ -use jclass::attributes::Attribute; +use jclass::attributes::{Attribute, InnerClassRecord}; use std::collections::HashMap; pub struct AttributesHelper { @@ -109,6 +109,14 @@ impl AttributesHelper { _ => None, } } + + pub fn get_inner_class_records(&self) -> Option> { + match self.data.get(&AttributeType::InnerClasses)? { + Attribute::InnerClasses { classes } => Some(classes.clone()), + _ => None, + } + } + } #[cfg(test)] diff --git a/vm/src/method_area/java_class.rs b/vm/src/method_area/java_class.rs index 89978805..4978baa9 100644 --- a/vm/src/method_area/java_class.rs +++ b/vm/src/method_area/java_class.rs @@ -32,6 +32,7 @@ pub(crate) struct JavaClass { instance_fields_hierarchy: OnceCell>>, fields_offset_mapping: OnceCell>, + declaring_class: Option, } #[derive(Debug)] @@ -71,6 +72,7 @@ impl JavaClass { parent: Option, interfaces: IndexSet, access_flags: u16, + declaring_class: Option, ) -> Self { let external_name = PRIMITIVE_TYPE_BY_CODE .get(this_class_name) @@ -90,6 +92,7 @@ impl JavaClass { static_fields_initialized: AtomicBool::new(false), instance_fields_hierarchy: OnceCell::new(), fields_offset_mapping: OnceCell::new(), + declaring_class, } } @@ -235,6 +238,10 @@ impl JavaClass { pub fn external_name(&self) -> &str { &self.external_name } + + pub fn declaring_class(&self) -> &Option { + &self.declaring_class + } } impl Methods { diff --git a/vm/src/method_area/method_area.rs b/vm/src/method_area/method_area.rs index 9d222171..ed212237 100644 --- a/vm/src/method_area/method_area.rs +++ b/vm/src/method_area/method_area.rs @@ -19,6 +19,7 @@ use std::io::Read; use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; use tracing::trace; +use jclass::attributes::Attribute; static METHOD_AREA: OnceCell = OnceCell::new(); @@ -163,6 +164,12 @@ impl MethodArea { let access_flags = class_file.access_flags().bits(); + let declaring_class = Self::get_declaring_class( + &class_file.attributes(), + &cpool_helper, + class_name.as_str(), + ); + Ok(( class_name.clone(), Arc::new(JavaClass::new( @@ -174,6 +181,7 @@ impl MethodArea { super_class_name, interface_names, access_flags, + declaring_class, )), )) } @@ -451,6 +459,7 @@ impl MethodArea { None, IndexSet::new(), PUBLIC | FINAL | ABSTRACT, + None, )) } @@ -467,6 +476,7 @@ impl MethodArea { Some("java/lang/Object".to_string()), IndexSet::from(["java/lang/Cloneable".to_string(), "java/io/Serializable".to_string()]), PUBLIC | FINAL | ABSTRACT, + None, )) } @@ -503,4 +513,27 @@ impl MethodArea { *guard = Some(thread_id); Ok(()) } + + fn get_declaring_class( + attributes: &[Attribute], + cpool_helper: &CPoolHelper, + class_name: &str, + ) -> Option { + let attribute_helper = AttributesHelper::new(attributes); + let inner_class_records = attribute_helper.get_inner_class_records()?; + + inner_class_records.iter().find_map(|inner_class_record| { + let inner_class_info_index = inner_class_record.inner_class_info_index(); + let inner_class_info = cpool_helper.get_class_name(inner_class_info_index)?; + + if class_name == inner_class_info { + let outer_class_info_index = inner_class_record.outer_class_info_index(); + let outer_class_info = cpool_helper.get_class_name(outer_class_info_index)?; + + Some(outer_class_info) + } else { + None + } + }) + } } diff --git a/vm/src/system_native/class.rs b/vm/src/system_native/class.rs index 2e27c667..30bd7dd4 100644 --- a/vm/src/system_native/class.rs +++ b/vm/src/system_native/class.rs @@ -194,3 +194,27 @@ fn get_interfaces0(class_ref: i32) -> crate::error::Result { }); Ok(result_ref) } + +pub(crate) fn get_declaring_class0_wrp(args: &[i32]) -> crate::error::Result> { + let clazz_ref = args[0]; + let declaring_class_ref = get_declaring_class0(clazz_ref)?; + Ok(vec![declaring_class_ref]) +} +fn get_declaring_class0(clazz_ref: i32) -> crate::error::Result { + let declaring_class_ref = with_method_area(|method_area| { + let class_name = method_area.get_from_reflection_table(clazz_ref)?; + let jc = method_area.get(&class_name)?; + let declaring_class_ref = jc + .declaring_class() + .as_ref() + .map(|declaring_class| { + let declaring_class_ref = method_area.load_reflection_class(declaring_class); + declaring_class_ref + }) + .unwrap_or(Ok(0)); + + declaring_class_ref + }); + + declaring_class_ref +}