88use PHPJava \Kernel \Structures \_ExceptionTable ;
99use PHPJava \Utilities \AttributionResolver ;
1010use PHPJava \Utilities \BinaryTool ;
11+ use PHPJava \Utilities \ClassResolver ;
1112use PHPJava \Utilities \Formatter ;
1213use PHPJava \Utilities \MethodNameResolver ;
1314use PHPJava \Utilities \TypeResolver ;
@@ -23,55 +24,48 @@ public function execute(): void
2324 $ cpInfo = $ this ->getConstantPool ();
2425 $ cp = $ cpInfo [$ this ->readUnsignedShort ()];
2526 $ nameAndTypeIndex = $ cpInfo [$ cp ->getNameAndTypeIndex ()];
27+ $ className = $ cpInfo [$ cpInfo [$ cp ->getClassIndex ()]->getClassIndex ()]->getString ();
28+ $ methodName = $ cpInfo [$ nameAndTypeIndex ->getNameIndex ()]->getString ();
2629 $ signature = $ cpInfo [$ nameAndTypeIndex ->getDescriptorIndex ()]->getString ();
2730 $ parsedSignature = Formatter::parseSignature ($ signature );
28- $ invokerClass = $ this ->popFromOperandStack ();
29-
30-
31- $ arguments = [];
32- if (($ length = $ parsedSignature ['arguments_count ' ] - 1 ) >= 0 ) {
33- $ arguments = array_fill (0 , $ length , null );
34- for ($ i = $ length ; $ i >= 0 ; $ i --) {
35- $ arguments [$ i ] = $ this ->popFromOperandStack ();
36- }
37- }
38-
39- $ methodName = $ cpInfo [$ nameAndTypeIndex ->getNameIndex ()]->getString ();
4031
41- if ($ this ->javaClassInvoker ->isInvoked ($ methodName , $ signature )) {
42- return ;
32+ // POP with right-to-left (objectref + arguments)
33+ $ collection = array_fill (0 , $ parsedSignature ['arguments_count ' ] + 1 , null );
34+ for ($ i = count ($ collection ) - 1 ; $ i >= 0 ; $ i --) {
35+ $ collection [$ i ] = $ this ->popFromOperandStack ();
4336 }
4437
45- $ this ->javaClassInvoker
46- ->addToSpecialInvokedList ($ methodName , $ signature );
47-
38+ $ objectref = $ collection [0 ];
4839
4940 try {
50- if ($ invokerClass instanceof JavaClass) {
51- if ($ invokerClass ->getInvoker ()->isInvoked ($ methodName , $ signature )) {
52- return ;
53- }
54-
55- $ invokerClass
56- ->getInvoker ()
57- ->addToSpecialInvokedList ($ methodName , $ signature );
5841
59- $ result = $ invokerClass
60- ->getInvoker ()
61- ->getDynamic ()
62- ->getMethods ()
63- ->call (
64- $ methodName ,
65- ...$ arguments
66- );
42+ // NOTE: first arguments is a class object. (PHPJava does not needed.)
43+ $ arguments = array_values (array_slice ($ collection , 1 ));
44+ $ methodName = $ cpInfo [$ nameAndTypeIndex ->getNameIndex ()]->getString ();
45+
46+ if ($ objectref instanceof JavaClass &&
47+ $ objectref ->getClassName () !== $ className
48+ ) {
49+ // If $objectref is not match $className, then change current class (I have no confidence).
50+ // See also: https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html#jvms-6.5.invokespecial
51+
52+ // FIXME: if $objectref has superclass, then refer superclass from $objectref
53+ // NOTE: This implementation is a ** first aid **.
54+ [$ resourceType , $ classObject ] = $ objectref
55+ ->getOptions ('class_resolver ' )
56+ ->resolve ($ className );
57+
58+ switch ($ resourceType ) {
59+ case ClassResolver::RESOLVED_TYPE_PACKAGES :
60+ $ objectref = new $ classObject (...$ arguments );
61+ break ;
62+ case ClassResolver::RESOLVED_TYPE_CLASS :
63+ throw new NotImplementedException ('This section is not implementation. ' );
64+ }
65+ } elseif ($ objectref instanceof JavaClass) {
66+ $ objectref = $ objectref (...$ arguments );
6767 } else {
68- $ result = call_user_func_array (
69- [
70- $ invokerClass ,
71- MethodNameResolver::resolve ($ methodName ),
72- ],
73- $ arguments
74- );
68+ $ objectref = new $ objectref (...$ arguments );
7569 }
7670 } catch (\Exception $ e ) {
7771 /**
@@ -104,9 +98,5 @@ public function execute(): void
10498 $ e
10599 );
106100 }
107-
108- if ($ parsedSignature [0 ]['type ' ] !== 'void ' ) {
109- $ this ->pushToOperandStack ($ result );
110- }
111101 }
112102}
0 commit comments