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.
156 lines
8.4 KiB
156 lines
8.4 KiB
# TypePHP change log
|
|
|
|
## 0.8.0
|
|
|
|
### Breaking: native scalar storage is now the default
|
|
|
|
`use native_types` has been removed. Inferred `int`, `float`, and `bool`
|
|
locals now use `php::Int`, `php::Float`, and `php::Bool` by default. Their
|
|
storage type is fixed and the compiler never promotes one of these locals to
|
|
`php::Var` merely because a later operation needs dynamic PHP semantics.
|
|
|
|
Two explicit escape hatches remain:
|
|
|
|
- `use varint_types` is a file-level mode that stores inferred integer values
|
|
in `php::Var`, preserving PHP's overflow-to-float, non-integral division,
|
|
and other Zend integer arithmetic behavior. It does not box `float` or
|
|
`bool` locals.
|
|
- `std::any($value)` erases the static type of that individual expression, so
|
|
a variable initialized from it uses `php::Var` and may participate in PHP
|
|
reference or dynamic-value operations.
|
|
|
|
For example, `$i = 100` is now permanently an integer local. Reusing `$i` as a
|
|
`foreach` key is rejected because PHP keys have type `int|string`; write
|
|
`$i = std::any(100)` or select `use varint_types` if this reuse is intentional.
|
|
Projects must remove `use native_types` and add the new compatibility mode only
|
|
to files that genuinely depend on Zend integer widening semantics.
|
|
|
|
Fixed `int`, `float`, `bool`, `string`, and `array` locals now use typed native
|
|
references. A stable local alias and an exact by-reference parameter on a
|
|
statically resolved TypePHP call lower directly to C++ `T&`; this path does not
|
|
box the value or allocate a Zend reference. Bindings must be unconditional,
|
|
one-time, function-local, and non-escaping. Rebinding, `unset`, reference
|
|
capture/return, and storing such a reference into PHP storage are rejected.
|
|
|
|
Dynamic calls and Closures retain the existing Zend reference path and require
|
|
explicit `std::ref()` / `toRef()`. A call-scoped bridge validates the value on
|
|
write-back and rejects an escaping temporary reference. Use `std::any()` for
|
|
unrestricted PHP reference identity. Fixed object/resource/stream,
|
|
high-precision, Native/typed-object, Box, and `std`-container locals remain
|
|
non-referenceable because those types already carry identity/handle semantics.
|
|
Typed properties and PHP array elements continue to use Zend references and
|
|
their normal type-source behavior.
|
|
|
|
TypePHP is always strict. Project sources no longer need
|
|
`declare(strict_types=1)`; the directive remains accepted as a redundant PHP
|
|
compatibility declaration, while `strict_types=0` is rejected.
|
|
|
|
### Breaking: compile-time API namespace cleanup
|
|
|
|
TypePHP compile-time APIs now occupy only two global class symbols:
|
|
|
|
- `Type::*` describes types used by extension-method metadata. It does not
|
|
execute conversions or other built-in operations.
|
|
- `std::*` contains TypePHP built-in compile-time functions.
|
|
|
|
As with PHP class and method names, the `std` / `Type` class names and `std`
|
|
method names are case-insensitive. `Type::Int` and the other `Type` members are
|
|
class constants, so their constant names remain case-sensitive under PHP rules.
|
|
|
|
The former global compile-time functions have changed as follows:
|
|
|
|
| Before 0.8 | Since 0.8 | Notes |
|
|
| --- | --- | --- |
|
|
| `any($value)` | `std::any($value)` | Erases the static type to `mixed/any`. |
|
|
| `refval($target)` | `std::ref($target)` | Explicit reference wrapper for call arguments. |
|
|
| `expected($condition)` | `std::expected($condition)` | Emits the `EXPECTED(...)` branch hint. |
|
|
| `unexpected($condition)` | `std::unexpected($condition)` | Emits the `UNEXPECTED(...)` branch hint. |
|
|
| `objval($value, Foo::class)` | `$value->toObject(Foo::class)` | Replaced by the existing keyword method. |
|
|
|
|
No compatibility functions are installed in the global namespace. Applications
|
|
may define and call their own `any()`, `refval()`, `expected()`, `unexpected()`,
|
|
and `objval()` functions without being intercepted by the compiler.
|
|
|
|
`std::ref()` retains the previous reference-wrapper restrictions: its target
|
|
must be a variable, array element, or object property, and it is only valid as a
|
|
call argument wrapper. `toRef()` remains the equivalent keyword method.
|
|
|
|
All projects using the old spellings must update their source and rebuild.
|
|
|
|
### Compatibility policy before 1.0
|
|
|
|
TypePHP is still pre-1.0 software. Public compiler APIs, TypePHP-specific source
|
|
syntax, generated-code interfaces, configuration, and packaging may change
|
|
between minor releases. Breaking changes will be documented here, but users
|
|
should review the change log and run their full test suite before upgrading.
|
|
|
|
---
|
|
|
|
## 0.8.0(中文)
|
|
|
|
### 破坏性变更:默认使用原生标量存储
|
|
|
|
`use native_types` 已移除。推断出的 `int`、`float`、`bool` 局部变量现在默认分别
|
|
使用 `php::Int`、`php::Float`、`php::Bool`。这些变量的存储类型一旦确定便不会因为
|
|
后续操作需要 PHP 动态语义而被编译器自动提升为 `php::Var`。
|
|
|
|
只保留两个显式出口:
|
|
|
|
- `use varint_types` 是文件级模式,使推断出的整数使用 `php::Var`,保留 PHP 的
|
|
整数溢出转浮点、整数除法产生非整数结果等 Zend 算术语义;它不会装箱 `float`
|
|
或 `bool`。
|
|
- `std::any($value)` 只擦除该表达式的静态类型。以它初始化的变量使用 `php::Var`,
|
|
可参与引用或其他动态值操作。
|
|
|
|
例如 `$i = 100` 现在固定为整数局部变量。由于 PHP 的 foreach key 类型为
|
|
`int|string`,之后复用 `$i` 作为 key 会在编译期报错;确需复用时,应写成
|
|
`$i = std::any(100)` 或在文件中声明 `use varint_types`。升级项目必须删除
|
|
`use native_types`,并且只为真正依赖 Zend 整数扩展语义的文件添加新兼容模式。
|
|
|
|
固定 `int`、`float`、`bool`、`string`、`array` 局部变量现在使用强类型原生引用。
|
|
稳定的局部别名,以及静态可解析 TypePHP 调用上的精确引用参数,会直接生成 C++ `T&`,
|
|
不装箱、不创建 Zend reference。绑定必须位于函数顶层、只发生一次且不得逃逸;重新绑定、
|
|
`unset`、引用捕获/返回,或把引用存入 PHP 槽位都会在编译期拒绝。
|
|
|
|
动态调用与 Closure 继续使用既有 Zend reference 路径,并要求显式使用 `std::ref()` /
|
|
`toRef()`。调用级 bridge 在返回时检查类型并拒绝临时引用逃逸;需要完整 PHP 引用身份时
|
|
应使用 `std::any()`。固定 object/resource/stream、高精度值、Native/typed object、Box
|
|
和 `std` 容器仍然禁止取引用,因为这些类型本身已有 identity/handle 语义。Typed
|
|
Property 与 PHP 数组元素继续使用 Zend reference 及其 type source 约束。
|
|
|
|
TypePHP 始终使用严格类型,项目源码不再需要 `declare(strict_types=1)`。该声明仍作为
|
|
冗余的 PHP 兼容语法被接受,而 `strict_types=0` 会被拒绝。
|
|
|
|
### 破坏性变更:整理编译期 API 命名空间
|
|
|
|
TypePHP 编译期 API 现在只占用两个全局类符号:
|
|
|
|
- `Type::*` 仅描述扩展方法元数据等场景使用的类型,不执行类型转换或其他内置操作。
|
|
- `std::*` 承载 TypePHP 内置编译期函数。
|
|
|
|
遵循 PHP 的类名与方法名规则,`std` / `Type` 类名以及 `std` 方法名均不区分
|
|
大小写。`Type::Int` 等成员属于类常量,因此其常量名仍按 PHP 规则区分大小写。
|
|
|
|
原全局编译期函数迁移如下:
|
|
|
|
| 0.8 之前 | 0.8 起 | 说明 |
|
|
| --- | --- | --- |
|
|
| `any($value)` | `std::any($value)` | 将静态类型降级为 `mixed/any`。 |
|
|
| `refval($target)` | `std::ref($target)` | 调用参数的显式引用包装器。 |
|
|
| `expected($condition)` | `std::expected($condition)` | 生成 `EXPECTED(...)` 分支提示。 |
|
|
| `unexpected($condition)` | `std::unexpected($condition)` | 生成 `UNEXPECTED(...)` 分支提示。 |
|
|
| `objval($value, Foo::class)` | `$value->toObject(Foo::class)` | 改用现有关键词方法。 |
|
|
|
|
TypePHP 不在全局命名空间安装兼容函数。应用可以自行定义并正常调用
|
|
`any()`、`refval()`、`expected()`、`unexpected()` 和 `objval()`,编译器不会拦截。
|
|
|
|
`std::ref()` 延续原引用包装限制:目标必须是变量、数组元素或对象属性,且只能作为
|
|
调用参数包装器使用。`toRef()` 仍是等价的关键词方法。
|
|
|
|
使用旧写法的项目必须修改源码并重新编译。
|
|
|
|
### 1.0 之前的兼容性策略
|
|
|
|
TypePHP 目前仍处于 1.0 之前。公开编译器 API、TypePHP 专有源码接口、生成代码接口、
|
|
配置和打包方式都可能在次版本中发生变化。破坏性变更会记录在本文件中;升级前请阅读
|
|
变更记录,并运行项目的完整测试。
|
|
|