Skip to content

Commit 94b58c2

Browse files
committed
Javaのメンバに対応
1 parent 33321aa commit 94b58c2

File tree

8 files changed

+223
-36
lines changed

8 files changed

+223
-36
lines changed

PHPJava/Core/JavaClass.php

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -575,26 +575,47 @@ public function appendTrace ($opcode, $programCounter, $stacks, $operands) {
575575
$this->Trace .= '#' . $programCounter . "\t" . sprintf('0x%02X', $opcode) . "\t" . $mnemonicName . (strlen($mnemonicName) < 8 ? "\t" : '') . "\t" . sizeof($stacks) . "\t" . implode("\t", $operands) . "\n";
576576

577577
}
578-
578+
579579
/**
580-
* トレース情報を別の変数に移し替えます。
581-
* @return void
580+
* トレースのヘッダー情報を定義します。
581+
*
582+
* @return string
582583
*/
583-
public function traceCompletion () {
584-
584+
private function traceHeader () {
585+
585586
$trace = '';
586587

587588
$trace .= $this->TraceHeader;
588589
$trace .= "PC\tOPCODE\tMNEMONIC\tSTACKS\tOPERAND(s)\n";
589590
$trace .= "----------------------------------------------------------------\n";
591+
return $trace;
592+
593+
}
590594

595+
/**
596+
* トレース情報を別の変数に移し替えます。
597+
* @return void
598+
*/
599+
public function traceCompletion () {
600+
601+
$trace = $this->traceHeader();
591602
$this->TraceBuffering[] = $trace . $this->Trace;
592603

593604
$this->TraceHeader = '';
594605
$this->Trace = '';
595606

596607

597608
}
609+
610+
/**
611+
* 現時点までに実行されたオペコードのトレース情報を出力します。
612+
*
613+
* @return string
614+
*/
615+
public function traceDump () {
616+
echo $this->traceHeader();
617+
echo $this->Trace;
618+
}
598619

599620
/**
600621
* トレース情報を出力します。
@@ -709,6 +730,7 @@ public function setInstance ($key, $value) {
709730
/**
710731
* このクラスにおける静的なメンバを返します
711732
*
733+
* @param mixed $key Javaで定義されている変数名を指定
712734
* @return mixed
713735
*/
714736
public function getStatic ($key) {
@@ -720,12 +742,44 @@ public function getStatic ($key) {
720742
/**
721743
* このクラスにおける動的なメンバを返します
722744
*
745+
* @param mixed $key Javaで定義されている変数名を指定
723746
* @return mixed
724747
*/
725748
public function getInstance ($key) {
726749

727750
return isset($this->ClassFields->Instances->{$key}) ? $this->ClassFields->Instances->{$key} : null;
728751

729752
}
753+
754+
/**
755+
* Javaのコンストラクタを呼びます。
756+
*
757+
* @param mixed $... コンストラクタに渡す引数を指定します。
758+
* @return JavaMethodInvoker
759+
*/
760+
public function construct () {
761+
$instance = new JavaMethodInvoker($this, true);
762+
763+
$args = func_get_args();
764+
765+
// find init
766+
foreach ($this->getMethods() as $method) {
767+
768+
if ($this->cpInfo[$method->getNameIndex()]->getString() === '<init>') {
769+
770+
// call init
771+
call_user_func_array(array(
772+
$instance,
773+
'<init>'
774+
), $args);
775+
break;
776+
777+
}
778+
779+
}
780+
781+
return $instance;
782+
783+
}
730784

731785
}

PHPJava/Enums/JavaMethodAccessFlagEnum.php renamed to PHPJava/Enums/JavaAccessFlagEnum.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
class JavaMethodAccessFlagEnum extends JavaEnum {
3+
class JavaAccessFlagEnum extends JavaEnum {
44

55
const CONSTANT_Public = 0x0001;
66
const CONSTANT_Private = 0x0002;

PHPJava/Invoker/JavaMethodInvoker.php

Lines changed: 118 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,104 @@
11
<?php
22

33
class JavaMethodInvoker extends JavaInvoker {
4+
5+
/**
6+
* @var bool コンストラクターが実行されているかどうかを判定します。
7+
*/
8+
private $_constructed = false;
9+
10+
/**
11+
*
12+
* @access private
13+
* @var bool インスタンス化されているかどうか判定します
14+
*/
15+
public function __construct(\JavaClass &$Class, $constructed = false) {
16+
parent::__construct($Class);
17+
$this->_constructed = $constructed;
18+
}
19+
20+
/**
21+
* Javaのメンバをコールします。
22+
*
23+
* @param $fieldName フィールド名
24+
* @return mixed
25+
*/
26+
public function __get ($fieldName) {
27+
28+
$cpInfo = $this->getClass()->getCpInfo();
429

5-
public function __call ($methodName, $arguments) {
30+
foreach ($this->getClass()->getFields() as $fieldInfo) {
631

7-
$cpInfo = $this->getClass()->getCpInfo();
32+
$cpFieldName = $cpInfo[$fieldInfo->getNameIndex()]->getString();
833

9-
foreach ($this->getClass()->getMethods() as $methodInfo) {
34+
if ($fieldName === $cpFieldName) {
35+
36+
$accessibility = $this->_getAccessiblity($fieldInfo);
37+
$fieldSignature = JavaClass::parseSignature($cpInfo[$fieldInfo->getDescriptorIndex()]->getString());
38+
39+
// 静的メンバの場合
40+
if (in_array('static', $accessibility)) {
41+
return $this->getClass()->getStatic($fieldName);
42+
}
43+
$type = 'JavaType' . ucfirst($fieldSignature[0]['type']);
44+
return new $type($this->getClass()->getInstance($fieldName));
45+
}
46+
}
47+
48+
throw new JavaInvokerException('undefined field "' . $fieldName . '"');
49+
50+
}
51+
52+
/**
53+
* Javaのメンバの値を設定します。
54+
*
55+
* @param string $fieldName フィールド名
56+
* @param mixed $value 書き換える値
57+
* @return mixed
58+
*/
59+
public function __set($fieldName, $value) {
60+
61+
$cpInfo = $this->getClass()->getCpInfo();
1062

11-
$cpMethodName = $cpInfo[$methodInfo->getNameIndex()]->getString();
63+
foreach ($this->getClass()->getFields() as $fieldInfo) {
1264

13-
if ($methodName === $cpMethodName) {
65+
$cpFieldName = $cpInfo[$fieldInfo->getNameIndex()]->getString();
1466

15-
$accessFlag = new JavaMethodAccessFlagEnum();
16-
$accessibility = array();
67+
if ($fieldName === $cpFieldName) {
68+
69+
$accessibility = $this->_getAccessiblity($fieldInfo);
70+
$fieldSignature = JavaClass::parseSignature($cpInfo[$fieldInfo->getDescriptorIndex()]->getString());
71+
72+
// 静的メンバの場合
73+
if (in_array('static', $accessibility)) {
74+
$this->getClass()->setStatic($fieldName, $value);
75+
return;
76+
}
77+
$this->getClass()->setInstance($fieldName, $value);
78+
return;
79+
}
80+
}
81+
82+
throw new JavaInvokerException('undefined field "' . $fieldName . '"');
83+
}
84+
85+
/**
86+
* Javaのメソッドをエミュレートします。
87+
*
88+
* @param $fieldName フィールド名
89+
* @return mixed
90+
*/
91+
public function __call ($methodName, $arguments) {
1792

18-
foreach ($accessFlag->getValues() as $value) {
93+
$cpInfo = $this->getClass()->getCpInfo();
1994

20-
if (($methodInfo->getAccessFlag() & $value) != 0) {
95+
foreach ($this->getClass()->getMethods() as $methodInfo) {
2196

22-
$accessibility[] = strtolower(preg_replace('/^CONSTANT_/', '', $accessFlag->getName($value)));
97+
$cpMethodName = $cpInfo[$methodInfo->getNameIndex()]->getString();
2398

24-
}
99+
if ($methodName === $cpMethodName) {
25100

26-
}
101+
$accessibility = $this->_getAccessiblity($methodInfo);
27102

28103
// メソッドのシグネチャを取得する
29104
$javaArguments = JavaClass::parseSignature($cpInfo[$methodInfo->getDescriptorIndex()]->getString());
@@ -98,13 +173,13 @@ public function __call ($methodName, $arguments) {
98173
$this->getClass()->appendTrace($opcode, $pointer, $stacks, $byteCodeStream->getOperands());
99174

100175
if ($returnValue !== null) {
176+
$this->getClass()->traceCompletion();
101177
return $returnValue;
102178
}
103179

104180
}
105181

106182
$this->getClass()->traceCompletion();
107-
108183
return;
109184

110185
}
@@ -120,10 +195,40 @@ public function __call ($methodName, $arguments) {
120195

121196
}
122197

198+
/**
199+
* 型の変換を行います
200+
*
201+
* @param mixed $value 変換対象を指定
202+
* @return int 変換された型を返します。
203+
*/
123204
public function valueOf ($value) {
124205

125206
return (int) $value;
126207

127208
}
128209

210+
/**
211+
* アクセス修飾子を取得します。
212+
*
213+
* @param JavaMethodInfo|JavaFieldInfo $info アクセス修飾子を取得したいストラクチャを指定
214+
* @return array アクセス修飾子を返します。
215+
*/
216+
private function _getAccessiblity ($info) {
217+
218+
$accessFlag = new JavaAccessFlagEnum();
219+
$accessibility = array();
220+
221+
foreach ($accessFlag->getValues() as $value) {
222+
223+
if (($info->getAccessFlag() & $value) != 0) {
224+
225+
$accessibility[] = strtolower(preg_replace('/^CONSTANT_/', '', $accessFlag->getName($value)));
226+
227+
}
228+
229+
}
230+
231+
return $accessibility;
232+
}
233+
129234
}

PHPJava/Platform/java/io/PrintStream.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ public function println ($arg) {
1212
// print stream
1313
echo $arg->getString() . "\n";
1414

15-
} else if (is_string($arg) || is_int($arg) || $arg instanceof \java\lang\String) {
15+
} else if (is_string($arg) ||
16+
is_int($arg) ||
17+
$arg instanceof \JavaType ||
18+
$arg instanceof \java\lang\String) {
1619

1720
echo $arg . "\n";
1821

PHPJava/Statements/JavaStatement_getstatic.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ public function execute () {
3232
$className = str_replace('/', '\\', $signature[0]['className']);
3333

3434
$this->pushStack(new $className());
35-
36-
} else {
37-
38-
throw new JavaStatementException('Has not class or field');
35+
return;
3936

4037
}
38+
39+
throw new JavaStatementException('Has not class or field');
40+
4141

4242
}
4343

PHPJava/Statements/JavaStatement_invokevirtual.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ public function execute () {
1414

1515
// signature
1616
$signature = JavaClass::parseSignature($cpInfo[$nameAndTypeIndex->getDescriptorIndex()]->getString());
17-
1817
$arguments = array();
1918

2019
for ($i = 0; $i < $signature['argumentsCount']; $i++) {
@@ -39,16 +38,15 @@ public function execute () {
3938

4039
// load platform
4140
$this->getInvoker()->loadPlatform($class);
41+
$cp->getClass()->traceDump();
4242

43-
$invokeClassName = '\\' . str_replace('/', '\\', $class);
44-
4543
$result = call_user_func_array(array(
4644

4745
$invokerClass,
4846
$cpInfo[$cpInfo[$cp->getNameAndTypeIndex()]->getNameIndex()]->getString()
4947

5048
), $arguments);
51-
49+
5250
// empty to array
5351
// $stacks = array();
5452

test.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class Test {
1111
* @return
1212
*/
1313
public int testInt (int value) {
14+
15+
System.out.println(this.testPrivateInteger(value));
1416
return value;
1517
}
1618

@@ -231,7 +233,6 @@ public static void main (String[] args) {
231233
System.out.println(i);
232234

233235
}
234-
235236

236237
}
237238

@@ -249,6 +250,10 @@ public static String test (int n, String m, int l, int i, int v, int k) {
249250

250251
}
251252

253+
private int testPrivateInteger (int value) {
254+
return value + 1 * 2 + 3;
255+
}
256+
252257
/*public void javaTest () {
253258
254259
testClass _c = new testClass();

0 commit comments

Comments
 (0)