Skip to content

Commit 5879fe3

Browse files
committed
Allows to compile the plain PHP file to a bytecode file of the JVM language.
1 parent 0b5e7f3 commit 5879fe3

File tree

194 files changed

+3851
-56
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

194 files changed

+3851
-56
lines changed

README-ja.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ PHPJava は **100% PHP のみ** で動きます
2828
- [English](./docs/compiler/README.md)
2929
- [日本語](./docs/compiler/README-ja.md)
3030

31+
## PHP のシンタックスによる JVM 言語
32+
- [English](./docs/jvm-lang/README.md)
33+
- [日本語](./docs/jvm-lang/README-ja.md)
34+
3135
## デモ
3236
![DEMO](https://user-images.githubusercontent.com/1282995/58679222-87070880-839d-11e9-8c98-978fdd0bb015.gif)
3337

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ Contribution guide is here:
2323
- [English](./README.md)
2424
- [日本語](./README-ja.md)
2525

26-
## Intermediate Code Compiler
26+
## The Intermediate Code Compiler
2727
- [English](./docs/compiler/README.md)
2828
- [日本語](./docs/compiler/README-ja.md)
2929

30+
## The JVM language of PHP syntax
31+
- [English](./docs/jvm-lang/README.md)
32+
- [日本語](./docs/jvm-lang/README-ja.md)
3033

3134
## DEMO
3235
![DEMO](https://user-images.githubusercontent.com/1282995/58679222-87070880-839d-11e9-8c98-978fdd0bb015.gif)

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,8 @@
5757
"git update-index --again"
5858
]
5959
}
60+
},
61+
"suggest": {
62+
"nikic/php-parser": "Allows to compile the plain PHP file to a bytecode file of the JVM language."
6063
}
6164
}

docs/compiler/README-ja.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,6 @@ var_dump(
625625

626626
| メソッド名 | 概要 |
627627
| ------- | --- |
628-
| `setMaxStacks(int)` | オペランドスタックに最大詰め込めるスタックの数を指定します。これは将来、 Operation Code から逆算可能であるため、廃止される予定です。 |
629-
| `setMaxLocals(int)` | 定義できるローカル変数の最大値を指定します。これは将来、 Operation Code から逆算可能であるため、廃止される予定です。 |
630628
| `setCode(string)` | オペレーションコード及びオペランドを定義します。 |
631629
| `setExceptionTable(ExceptionTable[])` | 例外が発生するテーブル情報を登録します。これは現在**未実装**です。 |
632630
| `setAttributes(Attributes[])` | Code Attribute に付属する属性情報を追加します。 |

docs/compiler/README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,6 @@ var_dump(
623623

624624
| Method name | Summary |
625625
| ------- | --- |
626-
| `setMaxStacks(int)` | Specify the max size for the operand stack. This will be deprecated by in the future. |
627-
| `setMaxLocals(int)` | Specify the max size of local variable. This will be deprecated in the future. |
628626
| `setCode(string)` | Define an opcode and operands. |
629627
| `setExceptionTable(ExceptionTable[])` | Define an exception tables to be thrown. This is **not yet implemented**. |
630628
| `setAttributes(Attributes[])` | Set the attributes for Code Attribute. |

docs/img/php_jvm_lang.gif

8.59 MB
Loading

docs/jvm-lang/README-ja.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# What is the JVM language of PHP syntax?
2+
PHPJava は PHP のシンタックスを用いて PHP を JVM 言語として扱うことが可能です。
3+
この機能は `nikic/php-parser` を用いて、 PHP を 抽象構文木 (a.k.a Abstract Syntax Tree) に分解し、 PHPJava のアセンブラを用いて
4+
JVM の中間コードを構成し、 PHP が JVM 言語として `java` コマンドで動作するようになります。
5+
これは、他のどの機能よりも試験的な実装で、やらなければいけないことがたくさんあります。
6+
7+
# デモ
8+
![DEMO](../img/php_jvm_lang.gif)
9+
10+
# Get started
11+
1. `HelloWorld.php` を用意します。
12+
```php
13+
<?php
14+
class HelloWorld
15+
{
16+
public static function main(array $strings)
17+
{
18+
echo "Hello World!";
19+
}
20+
}
21+
```
22+
23+
2. `PackageAssembler` を実行し、中間コードを構成します。
24+
25+
```php
26+
<?php
27+
use PHPJava\Compiler\Lang\PackageAssembler;
28+
use PHPJava\Compiler\Lang\Stream\FileStream;
29+
30+
(new PackageAssembler(
31+
(new FileStream(__DIR__ . '/HelloWorld.php'))
32+
// コンパイル後に出力されるディレクトリを指定します。
33+
->setDistributeDirectory(__DIR__ . '/dist')
34+
))->assemble();
35+
36+
```
37+
38+
3. `dist` ディレクトリに `HelloWorld.class` が生成されるので実行してみます。
39+
40+
```
41+
$ cd dist
42+
$ java HelloWorld
43+
```
44+
45+
実行すると `Hello World!` が出力されます。
46+
47+
# コンパイルについて
48+
## 互換性
49+
この機能は `JDK 8` としてコンパイルされます。
50+
51+
## 型について
52+
PHP の文字列出力の際に、文字列ではないリテラルやオブジェクトが渡された場合は、文字列に変換しようと試みます。
53+
例えば、 `1` という数値リテラルは、 Java 上では概ね下記のとおりに変換されます。
54+
55+
```java
56+
int number = 1;
57+
(new java.lang.Integer(number)).toString()
58+
```
59+
60+
PHPJava が構成するオペレーションコードは下記のとおりです。
61+
62+
```
63+
0: iconst_1
64+
1: istore_1
65+
2: getstatic #21 // Field java/lang/System.out:Ljava/io/PrintStream;
66+
5: new #9 // class java/lang/Integer
67+
8: dup
68+
9: iload_1
69+
10: invokespecial #7 // Method java/lang/Integer."<init>":(I)V
70+
13: invokevirtual #13 // Method java/lang/Integer.toString:()Ljava/lang/String;
71+
16: invokevirtual #25 // Method java/io/PrintStream.print:(Ljava/lang/String;)V
72+
```
73+
74+
## PHPRuntime.PHPStandard
75+
`PHPStandard` は PHP を実行するためのランタイムクラスを格納している名前空間です。
76+
77+
### PHPRuntime.PHPStandard.Constants (旧: PHPStandardClass)
78+
TBD
79+
80+
### PHPRuntime.PHPStandard.Classes
81+
TBD
82+
83+
### PHPRuntime.PHPStandard.Functions
84+
TBD
85+
86+
### PHPRuntime.GlobalStore
87+
TBD
88+
89+
## PHPRuntime.EntryPoint
90+
TBD
91+
92+
# TODO
93+
- [ ] 条件分岐の実装
94+
- [ ] ループ分の実装
95+
- [ ] PHP の関数呼び出しの実装
96+
- [ ] クラス外に書かれた箇所を main として扱うようなエントリーポイントの実装
97+
- [ ] Java Archive への対応

docs/jvm-lang/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# What is the JVM language of PHP syntax?
2+
PHPJava is able to become a JVM language with PHP syntax.
3+
This feature analyze to AST using `nikic/php-parser`, And PHPJava assemble a intermediately code with assembler in PHPJava, and you can run it as a JVM language with `java` command.
4+
This feature is a experimental implementation more than any other.
5+
6+
# DEMO
7+
![DEMO](../img/php_jvm_lang.gif)
8+
9+
# Get started
10+
1. Create a `HelloWorld.php`
11+
```php
12+
<?php
13+
class HelloWorld
14+
{
15+
public static function main(array $strings)
16+
{
17+
echo "Hello World!";
18+
}
19+
}
20+
```
21+
22+
2. Run `PackageAssembler`, and coordinate an intermediately code.
23+
24+
```php
25+
<?php
26+
use PHPJava\Compiler\Lang\PackageAssembler;
27+
use PHPJava\Compiler\Lang\Stream\FileStream;
28+
29+
(new PackageAssembler(
30+
(new FileStream(__DIR__ . '/HelloWorld.php'))
31+
// Specify output directory after compile is finished.
32+
->setDistributeDirectory(__DIR__ . '/dist')
33+
))->assemble();
34+
35+
```
36+
37+
3. To run generated `HelloWorld.class` in `dist` directory.
38+
39+
```
40+
$ cd dist
41+
$ java HelloWorld
42+
```
43+
44+
You'll get `Hello World!`.
45+
46+
# About compile
47+
## Compatibility
48+
This feature compile as the JDK 8.
49+
50+
## About types
51+
PHPJava will try to convert to a string when passed literal or object is not a string.
52+
For example, The number literal `1` will convert as below roughly on Java.
53+
54+
```java
55+
int number = 1;
56+
(new java.lang.Integer(number)).toString()
57+
```
58+
59+
PHPJava will assemble operation code as follows:
60+
61+
```
62+
0: iconst_1
63+
1: istore_1
64+
2: getstatic #21 // Field java/lang/System.out:Ljava/io/PrintStream;
65+
5: new #9 // class java/lang/Integer
66+
8: dup
67+
9: iload_1
68+
10: invokespecial #7 // Method java/lang/Integer."<init>":(I)V
69+
13: invokevirtual #13 // Method java/lang/Integer.toString:()Ljava/lang/String;
70+
16: invokevirtual #25 // Method java/io/PrintStream.print:(Ljava/lang/String;)V
71+
```
72+
73+
## PHPRuntime.PHPStandard
74+
`PHPStandard` is a namespace for runtime classes of PHP.
75+
76+
### PHPRuntime.PHPStandard.Constants (旧: PHPStandardClass)
77+
TBD
78+
79+
### PHPRuntime.PHPStandard.Classes
80+
TBD
81+
82+
### PHPRuntime.PHPStandard.Functions
83+
TBD
84+
85+
### PHPRuntime.GlobalStore
86+
TBD
87+
88+
## PHPRuntime.EntryPoint
89+
TBD

phpcs.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
</rule>
99

1010
<rule ref="Squiz.Classes.ValidClassName.NotCamelCaps">
11+
<exclude-pattern>./src/Compiler/Lang/Assembler/Bundler/Packages</exclude-pattern>
1112
<exclude-pattern>./src/Kernel/Types</exclude-pattern>
1213
<exclude-pattern>./src/Kernel/Mnemonics</exclude-pattern>
1314
<exclude-pattern>./src/Kernel/Structures</exclude-pattern>

src/Compiler/Builder/Attributes/Architects/Operation.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
use PHPJava\Core\JVM\Stream\BinaryWriter;
1010
use PHPJava\Exceptions\CompilerException;
1111

12-
class Operation extends Architect implements ArchitectInterface
12+
class Operation extends Architect implements ArchitectInterface, \IteratorAggregate
1313
{
14+
protected $calculateLDCWideOperationAutomatically = true;
15+
1416
/**
1517
* @var array
1618
*/
@@ -22,7 +24,23 @@ public function add(int $opcode, array $arguments = []): self
2224
return $this;
2325
}
2426

25-
public function getValue(): string
27+
public function set(int $index, int $opcode, array $arguments = []): self
28+
{
29+
$this->codes[$index] = [$opcode, $arguments];
30+
return $this;
31+
}
32+
33+
public function get(int $index): ?array
34+
{
35+
return $this->codes[$index] ?? null;
36+
}
37+
38+
public function getIterator()
39+
{
40+
return new \ArrayIterator($this->codes);
41+
}
42+
43+
public function make(): string
2644
{
2745
$writer = new BinaryWriter(fopen('php://memory', 'r+'));
2846
foreach ($this->codes as [$opcode, $arguments]) {
@@ -56,6 +74,6 @@ public function getValue(): string
5674

5775
public function __toString(): string
5876
{
59-
return $this->getValue();
77+
return $this->make();
6078
}
6179
}

0 commit comments

Comments
 (0)