33
44use PHPJava \Core \JavaClass ;
55use PHPJava \Exceptions \NotImplementedException ;
6+ use PHPJava \Exceptions \UnableToCatchException ;
7+ use PHPJava \Kernel \Attributes \CodeAttribute ;
8+ use PHPJava \Kernel \Structures \_ExceptionTable ;
69use PHPJava \Utilities \BinaryTool ;
710use PHPJava \Utilities \Formatter ;
811use PHPJava \Utilities \MethodNameResolver ;
12+ use PHPJava \Utilities \TypeResolver ;
913
1014final class _invokespecial implements OperationInterface
1115{
1216 use \PHPJava \Kernel \Core \Accumulator;
1317 use \PHPJava \Kernel \Core \ConstantPool;
18+ use \PHPJava \Kernel \Core \DependencyInjector;
1419
1520 public function execute (): void
1621 {
@@ -23,12 +28,10 @@ public function execute(): void
2328
2429 $ arguments = [];
2530
26- for ($ i = 0 ; $ i < $ parsedSignature ['arguments_count ' ]; $ i++ ) {
27- $ arguments [] = $ this ->popFromOperandStack ();
31+ for ($ i = $ signature ['arguments_count ' ] - 1 ; $ i >= 0 ; $ i -- ) {
32+ $ arguments [$ i ] = $ this ->popFromOperandStack ();
2833 }
2934
30- krsort ($ arguments );
31-
3235 $ methodName = $ cpInfo [$ nameAndTypeIndex ->getNameIndex ()]->getString ();
3336
3437 if ($ this ->javaClassInvoker ->isInvoked ($ methodName , $ signature )) {
@@ -38,30 +41,78 @@ public function execute(): void
3841 $ this ->javaClassInvoker
3942 ->addToSpecialInvokedList ($ methodName , $ signature );
4043
41- if ($ invokerClass instanceof JavaClass) {
42- if ($ invokerClass ->getInvoker ()->isInvoked ($ methodName , $ signature )) {
43- return ;
44- }
4544
46- $ invokerClass
47- ->getInvoker ()
48- ->addToSpecialInvokedList ($ methodName , $ signature );
49-
50- $ result = $ invokerClass
51- ->getInvoker ()
52- ->getDynamic ()
53- ->getMethods ()
54- ->call (
55- $ methodName ,
56- ...$ arguments
45+ try {
46+ if ($ invokerClass instanceof JavaClass) {
47+ if ($ invokerClass ->getInvoker ()->isInvoked ($ methodName , $ signature )) {
48+ return ;
49+ }
50+
51+ $ invokerClass
52+ ->getInvoker ()
53+ ->addToSpecialInvokedList ($ methodName , $ signature );
54+
55+ $ result = $ invokerClass
56+ ->getInvoker ()
57+ ->getDynamic ()
58+ ->getMethods ()
59+ ->call (
60+ $ methodName ,
61+ ...$ arguments
62+ );
63+ } else {
64+ $ reflectionClass = new \ReflectionClass (
65+ $ realInvokerClass = TypeResolver::convertPHPTypeToJavaType ($ invokerClass )
66+ );
67+ $ methodAccessor = $ reflectionClass ->getMethod ($ methodName );
68+
69+ if ($ document = $ methodAccessor ->getDocComment ()) {
70+ $ prependInjections = $ this ->getNativeAnnotateInjections ($ document );
71+ if (!empty ($ prependInjections )) {
72+ array_unshift (
73+ $ arguments ,
74+ ...$ prependInjections
75+ );
76+ }
77+ }
78+
79+ $ result = call_user_func_array (
80+ [
81+ $ invokerClass ,
82+ MethodNameResolver::resolve ($ methodName ),
83+ ],
84+ $ arguments
5785 );
58- } else {
59- $ result = call_user_func_array (
60- [
61- $ invokerClass ,
62- MethodNameResolver::resolve ($ methodName ),
63- ],
64- $ arguments
86+ }
87+ } catch (\Exception $ e ) {
88+ /**
89+ * @var $codeAttribute CodeAttribute
90+ */
91+ $ codeAttribute = AttributionResolver::resolve (
92+ $ this ->getAttributes (),
93+ CodeAttribute::class
94+ );
95+
96+ $ expectedClass = Formatter::convertPHPNamespacesToJava (get_class ($ e ));
97+
98+ foreach ($ codeAttribute ->getExceptionTables () as $ exception ) {
99+ /**
100+ * @var $exception _ExceptionTable
101+ */
102+ $ catchClass = Formatter::convertPHPNamespacesToJava ($ cpInfo [$ cpInfo [$ exception ->getCatchType ()]->getClassIndex ()]->getString ());
103+ if ($ catchClass === $ expectedClass &&
104+ $ exception ->getStartPc () <= $ this ->getProgramCounter () &&
105+ $ exception ->getEndPc () >= $ this ->getProgramCounter ()
106+ ) {
107+ $ this ->setOffset ($ exception ->getHandlerPc ());
108+ return ;
109+ }
110+ }
111+
112+ throw new UnableToCatchException (
113+ $ expectedClass . ': ' . $ e ->getMessage (),
114+ 0 ,
115+ $ e
65116 );
66117 }
67118
0 commit comments