Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ make test # builds php-compiler:22.04-dev if needed, then memory-safe CI in D
|-----------|---------|--------|
| Per-file AOT lint | `php bin/compile.php -l lib/*.php` | ✅ All **14** top-level `lib/*.php` units ([#534](https://github.com/PurHur/php-compiler/pull/534)) |
| Bootstrap fixture lint | `php script/bootstrap-aot-lint.php` | ✅ **11** procedural lint targets |
| Bootstrap native link | `make bootstrap-aot-link` | ✅ **9** native link targets (incl. `require_chain`, `throw_logic`, [#57](https://github.com/PurHur/php-compiler/issues/57), [#120](https://github.com/PurHur/php-compiler/issues/120)) |
| Bootstrap native link | `make bootstrap-aot-link` | ✅ **11** native link targets (incl. `require_chain`, `throw_logic`, [#538](https://github.com/PurHur/php-compiler/pull/538), [#545](https://github.com/PurHur/php-compiler/pull/545)) |
| **Compiler self-compile** | `./script/bootstrap-selfhost-lint.sh` | ✅ Bundled `lib/Compiler.php` AOT **lint** passes ([#212](https://github.com/PurHur/php-compiler/issues/212), [#78](https://github.com/PurHur/php-compiler/issues/78)); native `-o` run not yet |

When the compiler successfully compiles itself, this section will be updated with the exact gate command, date, and PR reference.
Expand Down
28 changes: 14 additions & 14 deletions docs/bootstrap-inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -1664,13 +1664,13 @@ These `LogicException` messages indicate CFG ops or expressions not yet lowered:
- new JIT\Call\Vararg (line 160)
- new JIT\Call\Native (line 163)
- new ext\standard\boolval (line 327)
- new Variable (line 538)
- new OpCode (line 605)
- new Variable (line 805)
- new Variable (line 1100)
- new Operand\Literal (line 1187)
- new Operand\Literal (line 1191)
- new Operand\Literal (line 1195)
- new Variable (line 545)
- new OpCode (line 612)
- new Variable (line 816)
- new Variable (line 1111)
- new Operand\Literal (line 1198)
- new Operand\Literal (line 1202)
- new Operand\Literal (line 1206)
- 14 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler

### `lib/JIT/Analyzer.php`
Expand Down Expand Up @@ -2153,13 +2153,13 @@ These `LogicException` messages indicate CFG ops or expressions not yet lowered:
**Warnings** (review for bootstrap subset):
- new Variable (line 78)
- new Variable (line 83)
- new Func\PHP (line 275)
- new ClassEntry (line 346)
- new ObjectEntry (line 358)
- new Exception (line 480)
- new Exception (line 482)
- new VM\ClassProperty (line 510)
- new Func\PHP (line 519)
- new Func\PHP (line 297)
- new ClassEntry (line 368)
- new ObjectEntry (line 380)
- new Exception (line 502)
- new Exception (line 504)
- new VM\ClassProperty (line 532)
- new Func\PHP (line 541)
- 4 class method(s) — PHPCfg Op\Stmt\ClassMethod not lowered in Compiler

### `lib/VM/ClassEntry.php`
Expand Down
6 changes: 4 additions & 2 deletions docs/bootstrap-profile.json
Original file line number Diff line number Diff line change
Expand Up @@ -352,13 +352,15 @@
"test/bootstrap-aot/instanceof_check.php",
"test/bootstrap-aot/minimal_class.php",
"test/bootstrap-aot/namespace_hello.php",
"test/bootstrap-aot/nullable_types.php"
"test/bootstrap-aot/nullable_types.php",
"test/bootstrap-aot/require_chain/main.php",
"test/bootstrap-aot/throw_logic.php"
],
"totals": {
"inventory_files": 300,
"excluded": 2,
"eligible": 298,
"aot_lint_targets": 12,
"aot_link_targets": 9
"aot_link_targets": 11
}
}
16 changes: 8 additions & 8 deletions docs/bootstrap-selfhost.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ North star: compile a **subset** of php-compiler with itself (native AOT), then
| Phase A inventory | `php script/bootstrap-inventory.php --check` | ✅ **300** files on `bin/vm.php` path; **10** source blockers (only `lib/AOT/Linker.php`, `lib/VM/HashTable.php` — both excluded) |
| Phase B lib AOT lint | `php bin/compile.php -l lib/*.php` (with `script/php-env.sh`) | ✅ **14/14** top-level `lib/*.php` units ([#534](https://github.com/PurHur/php-compiler/pull/534)) |
| Phase B fixture lint | `php script/bootstrap-aot-lint.php` | ✅ **11** procedural targets under `test/bootstrap-aot/` + `examples/000-HelloWorld` |
| Phase C native run | `make bootstrap-aot-link` or `./script/bootstrap-aot-link.sh` | ✅ Link + execute **9** `aot_link_targets` (stdout vs Zend PHP) |
| Phase C native run | `make bootstrap-aot-link` or `./script/bootstrap-aot-link.sh` | ✅ Link + execute **11** `aot_link_targets` (stdout vs Zend PHP) |
| Bundled `lib/Compiler.php` lint | `./script/bootstrap-selfhost-lint.sh` | ✅ `test/selfhost/compiler_minimal/main.php` + literal `require_once` closure (no `vendor/`) |

Regenerate: `make bootstrap-profile` (inventory + profile + optional `bootstrap-aot-lint`). Phase C: `make bootstrap-aot-link` (or `php script/bootstrap-aot-lint.php --link`). Bundled compiler lint: `./script/bootstrap-selfhost-lint.sh`.
Expand All @@ -18,15 +18,14 @@ Regenerate: `make bootstrap-profile` (inventory + profile + optional `bootstrap-

These fixtures pass `compile.php -l` but are excluded from `aot_link_targets` in `script/bootstrap-lib.php` until JIT/link gaps close:

- `test/bootstrap-aot/class_const_fetch.php` — `Expr_ClassConstFetch` runtime fetch ([#84](https://github.com/PurHur/php-compiler/issues/84))
- `test/bootstrap-aot/instanceof_check.php` — `instanceof` lowering ([#530](https://github.com/PurHur/php-compiler/issues/530) partial)
- `test/bootstrap-aot/try_catch.php` — try/catch CFG link + VM unwind ([#57](https://github.com/PurHur/php-compiler/issues/57))

## Blockers to compile `lib/Compiler.php` (priority order)

1. **Namespaces** ([#84](https://github.com/PurHur/php-compiler/issues/84)) — every `lib/` unit uses `namespace PHPCompiler;` (per-file and bundled minimal subset `-l` pass; native link/run pending)
2. **Class methods** ([#58](https://github.com/PurHur/php-compiler/issues/58), [#145](https://github.com/PurHur/php-compiler/issues/145)) — inventory warns on `Op\Stmt\ClassMethod` across `lib/`
3. **Nullable typed properties** — `?Type` on fields with `= null` defaults ✅ (`php-types-fromvalue-null.patch`, `test/bootstrap-aot/class_nullable_property.php`); nullable **parameters** ✅ (`php-types-nullable-return.patch`, `test/bootstrap-aot/nullable_types.php`)
4. **Try/catch** ([#57](https://github.com/PurHur/php-compiler/issues/57)) — `lib/Runtime.php`, error paths (`throw` terminal lint ✅; catch paths pending)
4. **Try/catch** ([#57](https://github.com/PurHur/php-compiler/issues/57)) — `lib/Runtime.php`, error paths (`throw` terminal link ✅ [#538](https://github.com/PurHur/php-compiler/pull/538); catch/unwind link pending)
5. **LLVM linker** — `lib/AOT/Linker.php` uses `shell_exec` (excluded from profile; keep external `clang` for now)
6. **Generators** — `lib/VM/HashTable.php` (excluded)

Expand All @@ -40,10 +39,11 @@ Add scripts under `test/bootstrap-aot/*.php` — picked up automatically by `scr
- `minimal_class.php` — one public method (ClassMethod lowering)
- `class_nullable_property.php` — nullable property with `= null` default
- `class_constants.php` — class `Const_` declarations; Phase C link ✅ ([#520](https://github.com/PurHur/php-compiler/issues/520), [#536](https://github.com/PurHur/php-compiler/pull/536))
- `class_const_fetch.php` — `ClassName::CONST` fetch (lint ✅; link pending)
- `instanceof_check.php` — `instanceof` expression (lint ✅; link pending)
- `throw_logic.php` — `throw` terminal (lint ✅; link pending)
- `require_chain/main.php` — `require_once` helper with shared functions (lint ✅; link pending)
- `class_const_fetch.php` — `ClassName::CONST` fetch; Phase C link ✅ ([#545](https://github.com/PurHur/php-compiler/pull/545))
- `instanceof_check.php` — `instanceof` expression; Phase C link ✅ ([#545](https://github.com/PurHur/php-compiler/pull/545))
- `throw_logic.php` — `throw` terminal; Phase C link ✅ ([#538](https://github.com/PurHur/php-compiler/pull/538))
- `require_chain/main.php` — `require_once` helper with shared functions; Phase C link ✅ ([#538](https://github.com/PurHur/php-compiler/pull/538))
- `try_catch.php` — try/catch CFG (lint ✅; link pending)

Per-file `php bin/compile.php -l lib/*.php` passes for all 14 top-level units after class-const and throw lowering ([#520](https://github.com/PurHur/php-compiler/issues/520), [#529](https://github.com/PurHur/php-compiler/issues/529)). **Bundled** minimal compiler closure: `test/selfhost/compiler_minimal/main.php` (gate: `./script/bootstrap-selfhost-lint.sh`).

Expand Down
15 changes: 13 additions & 2 deletions lib/JIT.php
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,13 @@ private function compileBlockInternal(
$value = $this->context->getVariableFromOp($block->getOperand($op->arg2));
$this->assignOperand($block->getOperand($op->arg1), $value->castTo(Variable::TYPE_NATIVE_BOOL));
break;
case OpCode::TYPE_CAST_STRING:
$value = $this->context->getVariableFromOp($block->getOperand($op->arg2));
$this->assignOperand(
$block->getOperand($op->arg1),
JIT\JitNativeString::coerce($this->context, $value)
);
break;
case OpCode::TYPE_ECHO:
case OpCode::TYPE_PRINT:
$argOffset = $op->type === OpCode::TYPE_ECHO ? $op->arg1 : $op->arg2;
Expand Down Expand Up @@ -704,8 +711,12 @@ private function compileBlockInternal(
}
return $origBasicBlock;
case OpCode::TYPE_THROW:
// AOT lint: throw terminal lowering only; no JIT emission yet (issue #57).
break;
$throwBlock = $builder->getInsertBlock();
$builder->positionAtEnd($throwBlock);
$this->context->freeDeadVariables($func, $throwBlock, $block);
$this->context->builder->call($this->context->lookupFunction('abort'));
$this->context->llvm->lib->LLVMBuildUnreachable($this->context->builder->builder);
return $origBasicBlock;
case OpCode::TYPE_RETURN_VOID:
$returnBlock = $builder->getInsertBlock();
$builder->positionAtEnd($returnBlock);
Expand Down
9 changes: 8 additions & 1 deletion lib/JIT.pre
Original file line number Diff line number Diff line change
Expand Up @@ -729,8 +729,15 @@ class JIT {
$lit = new Operand\Literal($vm->toBool());
$lit->type = Type::bool();
return Variable::fromLiteral($this->context, $lit);
case VM\Variable::TYPE_NULL:
return new Variable(
$this->context,
Variable::TYPE_NULL,
Variable::KIND_VALUE,
$this->context->getTypeFromString('__value__*')->constNull()
);
default:
throw new \LogicException('Unsupported default parameter type for JIT');
throw new \LogicException('Unsupported default parameter type for JIT (vm type ' . $vm->type . ')');
}
}

Expand Down
4 changes: 1 addition & 3 deletions script/bootstrap-lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,7 @@ function bootstrapDefaultAotLintTargets(string $root): array
function bootstrapDefaultAotLinkTargets(array $lintTargets): array
{
$pendingUserFunc = [
'test/bootstrap-aot/require_chain/main.php', // multi-file require_once (#120)
'test/bootstrap-aot/throw_logic.php', // throw terminal lowering (#57)
'test/bootstrap-aot/try_catch.php', // try/catch CFG lint (#57); VM unwind pending
'test/bootstrap-aot/try_catch.php', // try/catch CFG link (#57); VM unwind pending
];

return array_values(array_filter(
Expand Down