TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
5.6 KiB
48 lines
5.6 KiB
<!doctype html><html lang="zh"><head><meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>编译流水线</title>
|
|
<script src="../script/mermaid.min.js"></script>
|
|
<script>document.addEventListener('DOMContentLoaded',function(){if(window.mermaid)mermaid.initialize({startOnLoad:true});});</script>
|
|
<style>
|
|
:root{--bg:#0f1117;--fg:#e6e6e6;--muted:#9aa0aa;--accent:#6ea8fe;--card:#171a21;--border:#262b36;}
|
|
*{box-sizing:border-box}
|
|
body{margin:0;font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;background:var(--bg);color:var(--fg);line-height:1.65}
|
|
.wrap{max-width:900px;margin:0 auto;padding:32px 24px 80px}
|
|
h1,h2,h3{color:#fff;line-height:1.3;margin-top:1.6em}
|
|
h1{border-bottom:1px solid var(--border);padding-bottom:.3em}
|
|
a{color:var(--accent);text-decoration:none}
|
|
a:hover{text-decoration:underline}
|
|
code{background:#0b0d12;padding:.15em .4em;border-radius:4px;font-size:.9em}
|
|
pre{background:#0b0d12;border:1px solid var(--border);border-radius:8px;padding:14px;overflow:auto}
|
|
pre code{background:none;padding:0}
|
|
table{border-collapse:collapse;width:100%;margin:1em 0}
|
|
th,td{border:1px solid var(--border);padding:8px 10px;text-align:left}
|
|
th{background:var(--card)}
|
|
blockquote{border-left:3px solid var(--accent);margin:1em 0;padding:.2em 1em;color:var(--muted);background:var(--card)}
|
|
hr{border:none;border-top:1px solid var(--border);margin:2em 0}
|
|
</style></head>
|
|
<body><div class="wrap"><h1>编译流水线</h1>
|
|
<p>TypePHP 的核心入口是 <code>bin/tpc.php</code>,它通过 <code>main()</code> 串起整条流水线:<code>prepare → convert → compile → build → run</code>。本章用一张图和一个阶段表把全链路讲清楚。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\bin\tpc.php#L1-L9">bin/tpc.php</a> · <a href="file:///D:\git\php\aot-compiler\src\compiler.php#L4-L46">src/compiler.php</a></p>
|
|
<h2>总体流程</h2>
|
|
<pre class="mermaid">flowchart TD
|
|
A["main(argc, argv)"] --> B["prepare(argv)\n扫描 PHP 文件 + 预处理"]
|
|
B --> C["convert(files)\nPHP AST → C++ 源文件"]
|
|
C --> D{"--dry?"}
|
|
D -- "是" --> Z["仅输出 C++,结束"]
|
|
D -- "否" --> E["compile(sourceFiles)\nC++ → .o / .obj"]
|
|
E --> F["build(objectFiles)\n链接为二进制 / 库 / 扩展"]
|
|
F --> G{"--run?"}
|
|
G -- "是" --> H["run(binary)\n立即执行"]
|
|
G -- "否" --> Z</pre>
|
|
<p><code>.prof</code> 后缀会被切换为 <code>profileAnalyze</code> 模式,调用 <code>pprof --web</code> 做性能剖析。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\compiler.php#L14-L18">src/compiler.php</a> · <a href="file:///D:\git\php\aot-compiler\src\compiler.php#L26-L45">src/compiler.php</a></p>
|
|
<h2>各阶段职责</h2>
|
|
<table><thead><tr><th>阶段</th><th>方法</th><th>关键工作</th></tr></thead><tbody><tr><td>准备</td><td><code>Translator::prepare()</code></td><td>扫描所有 PHP 文件、解析命令行、构建符号表(类/函数/常量/属性)</td></tr><tr><td>转换</td><td><code>Translator::convert()</code> → <code>convertFile()</code> → <code>doConvert()</code></td><td>对每个 PHP 文件解析 AST,跑 Transform 访客,生成 <code>.cc</code> 与 <code>_arginfo.h</code></td></tr><tr><td>编译</td><td><code>Translator::compile()</code></td><td>追加 phpx misc 源文件、准备 PCH、单进程或 <code>pcntl</code> 并行编译</td></tr><tr><td>构建</td><td><code>Translator::build()</code></td><td>调用原生链接器把目标文件 + 资源文件链接成最终产物</td></tr><tr><td>运行</td><td><code>Translator::run()</code></td><td>仅在 <code>bin</code> 模式且带 <code>--run</code> 时执行产物</td></tr></tbody></table>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L504-L527">src/Translator.php</a> · <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L1419-L1447">src/Translator.php</a> · <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L1649-L1680">src/Translator.php</a></p>
|
|
<h2>转换阶段的两趟扫描</h2>
|
|
<p><code>doConvert()</code> 内部做了两件事(<a href="file:///D:\git\php\aot-compiler\src\Translator.php#L2455-L2537">src/Translator.php</a>):</p>
|
|
<ol><li><strong>AST 遍历</strong>:用 <code>NodeTraverser</code> 串联 <code>NameResolver</code>、<code>Transform\Visitor</code>、<code>ConstantExpressionValidationVisitor</code>、<code>RuntimeAttributeFactoryLowering</code> 四个访客,做名称解析、编译期属性 lowering、常量表达式校验。</li><li><strong>语句分发</strong>:遍历顶层语句,按 <code>Stmt_Class</code> / <code>Stmt_Function</code> / <code>Stmt_Const</code> 等类型调用对应的 <code>parseXxx()</code>,最后为每个类、接口、函数生成 C++ 包装代码(<code>genClassWrapper</code> / <code>genFunctionWrapper</code>)。</li></ol>
|
|
<blockquote>前端的解析/符号表逻辑在 <a href="pages/preprocessor.html">preprocessor</a> 与 <a href="pages/transform.html">transform</a> 章节展开;C++ 生成细节在 <a href="pages/generator.html">generator</a>。</blockquote>
|
|
<h2>关键文件</h2>
|
|
<ul><li><code>src/compiler.php</code> — 顶层 <code>main()</code> 与 <code>.prof</code> 剖析模式。</li><li><code>src/Translator.php</code> — 流水线编排 + 构建/链接/缓存。</li><li><code>src/Preprocessor.php</code> / <code>src/CompilerBase.php</code> — 解析、符号收集、C++ 代码发射(占 7000+ 行,是编译器主体)。</li></ul></div></body></html> |