55use PHPJava \Core \JavaClassInvoker ;
66use PHPJava \Core \JVM \Stream \BinaryReader ;
77use PHPJava \Exceptions \IllegalJavaClassException ;
8+ use PHPJava \Exceptions \RuntimeException ;
89use PHPJava \Exceptions \UndefinedMethodException ;
910use PHPJava \Exceptions \UndefinedOpCodeException ;
1011use PHPJava \Kernel \Attributes \AttributeInfo ;
@@ -29,6 +30,17 @@ public function __construct(JavaClassInvoker $javaClassInvoker, array $methods)
2930
3031 public function __call ($ name , $ arguments )
3132 {
33+ $ getCodeAttribute = function ($ attributes ) {
34+ foreach ($ attributes as $ attribute ) {
35+ /**
36+ * @var AttributeInfo $attribute
37+ */
38+ if ($ attribute ->getAttributeData () instanceof CodeAttribute) {
39+ return $ attribute ->getAttributeData ();
40+ }
41+ }
42+ return null ;
43+ };
3244 /**
3345 * @var _MethodInfo|null $method
3446 */
@@ -37,7 +49,7 @@ public function __call($name, $arguments)
3749 throw new UndefinedMethodException ('Undefined ' . $ name . ' method. ' );
3850 }
3951
40- $ codeAttribute = $ this -> getCodeAttribute ($ method ->getAttributes ());
52+ $ codeAttribute = $ getCodeAttribute ($ method ->getAttributes ());
4153
4254 if ($ codeAttribute === null ) {
4355 throw new IllegalJavaClassException ('Java class does not having code attribution. ' );
@@ -47,20 +59,34 @@ public function __call($name, $arguments)
4759 fwrite ($ handle , $ codeAttribute ->getCode ());
4860 rewind ($ handle );
4961
62+ // debug code attribution with HEX
63+ // var_dump(implode(' ', str_split(bin2hex($codeAttribute->getCode()), 2)));
64+
5065 $ reader = new BinaryReader ($ handle );
5166
52- $ localStorage = array_slice ($ arguments , 0 , 4 );
67+ $ localStorage = [
68+ $ arguments [0 ] ?? null ,
69+ $ arguments [1 ] ?? null ,
70+ $ arguments [2 ] ?? null ,
71+ $ arguments [3 ] ?? null ,
72+ ];
5373
5474 $ stacks = [];
5575 $ opcodeMap = new OpCode ();
76+ $ executedCounter = 0 ;
5677 while ($ reader ->getOffset () < $ codeAttribute ->getOpCodeLength ()) {
78+ if (++$ executedCounter > \PHPJava \Core \JVM \Parameter \Invoker::MAX_STACK_EXCEEDED ) {
79+ throw new RuntimeException ('Max stack exceeded. PHPJava has been stopped by safety guard. Maybe Java class has illegal program counter, stacks, or OpCode. ' );
80+ }
5781 $ cursor = $ reader ->readUnsignedByte ();
5882 $ opcode = $ opcodeMap ->getName ($ cursor );
5983 if ($ opcode === null ) {
6084 throw new UndefinedOpCodeException ('Undefined OpCode ' . sprintf ('0x%X ' , $ cursor ) . '. ' );
6185 }
6286 $ pointer = $ reader ->getOffset () - 1 ;
6387
88+ var_dump ($ cursor , $ pointer );
89+
6490 $ fullName = '\\PHPJava \\Kernel \\OpCode \\' . $ opcode ;
6591
6692 echo 'Mnemonic: ' . $ opcode . "\n" ;
@@ -80,17 +106,4 @@ public function __call($name, $arguments)
80106
81107 return null ;
82108 }
83-
84- private function getCodeAttribute (array $ attributes ): ?CodeAttribute
85- {
86- foreach ($ attributes as $ attribute ) {
87- /**
88- * @var AttributeInfo $attribute
89- */
90- if ($ attribute ->getAttributeData () instanceof CodeAttribute) {
91- return $ attribute ->getAttributeData ();
92- }
93- }
94- return null ;
95- }
96109}
0 commit comments