refactor(php): 重构编译器对象管理逻辑

- 将对象存储从 $this->objects 迁移到 $this->context->objects
- 重命名 parseFinallyAssign 方法为 parseAssignFinally
- 添加 addObject 辅助方法统一对象注册逻辑
- 优化类型推断中的对象存储操作
- 更新测试用例中的类型转换语法
- 跳过不支持的属性测试用例
pull/1/head
韩天峰 6 months ago
parent f73a6cb6ac
commit f17ffa6b6f
  1. 36
      src/Php/CompilerBase.php
  2. 10
      tests/aot/pi.phpt
  3. 2
      tests/aot/prop-001.phpt

@ -271,12 +271,12 @@ class CompilerBase extends \PhpAot\Core\Translator
public function isTypedObject(string $object): bool public function isTypedObject(string $object): bool
{ {
return isset($this->objects[$object]); return isset($this->context->objects[$object]);
} }
public function getObjectType(string $object): string public function getObjectType(string $object): string
{ {
return $this->objects[$object] ?? 'stdClass'; return $this->context->objects[$object] ?? 'stdClass';
} }
public function parseExpr(NodeAbstract $expr) public function parseExpr(NodeAbstract $expr)
@ -1189,7 +1189,7 @@ class CompilerBase extends \PhpAot\Core\Translator
$list[] = $this->getIndent() . $tmpVar . ' = ' . $this->parseExpr($next); $list[] = $this->getIndent() . $tmpVar . ' = ' . $this->parseExpr($next);
$right = new Variable($tmpVar); $right = new Variable($tmpVar);
foreach ($chain as $var) { foreach ($chain as $var) {
$list[] = $this->getIndent() . $this->parseFinallyAssign($var, $right); $list[] = $this->getIndent() . $this->parseAssignFinally($var, $right);
} }
return implode(";\n" . $this->getIndent(), $list); return implode(";\n" . $this->getIndent(), $list);
@ -1215,10 +1215,10 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($right->getType() === 'Expr_Assign') { if ($right->getType() === 'Expr_Assign') {
return $this->parseRightAssociativeAssign($left, $right); return $this->parseRightAssociativeAssign($left, $right);
} }
return $this->parseFinallyAssign($left, $right); return $this->parseAssignFinally($left, $right);
} }
protected function parseFinallyAssign($left, $right): string protected function parseAssignFinally($left, $right): string
{ {
if ($left instanceof Node\Expr\List_) { if ($left instanceof Node\Expr\List_) {
$items = $left->items; $items = $left->items;
@ -1263,14 +1263,14 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($this->isVarExpr($left)) { if ($this->isVarExpr($left)) {
// 类型推断,获取对象的类名 // 类型推断,获取对象的类名
if ($this->isNewExpr($right) and $this->isNameExpr($right->class)) { if ($this->isNewExpr($right) and $this->isNameExpr($right->class)) {
$class = $this->parseIdentifier($right->class); $class = $this->parseIdentifier($right->class);
$this->context->objects[$var] = $this->getNamespacedClassName($class); $this->addObject($var, $this->getNamespacedClassName($class));
$type = self::TYPE_OBJECT; $type = self::TYPE_OBJECT;
} elseif ($this->isFuncCallExpr($right) and $this->isNameExpr($right->name)) { } elseif ($this->isFuncCallExpr($right) and $this->isNameExpr($right->name)) {
$fn = $this->parseIdentifier($right->name); $fn = $this->parseIdentifier($right->name);
if (count($right->args) === 2 and $fn === 'objval' and $this->isScalarString($right->args[1]->value)) { if (count($right->args) === 2 and $fn === 'objval' and $this->isScalarString($right->args[1]->value)) {
$this->context->objects[$var] = $this->getNamespacedClassName($this->parseIdentifier($right->args[1]->value)); $this->addObject($var, $this->getNamespacedClassName($this->parseIdentifier($right->args[1]->value)));
$type = self::TYPE_OBJECT; $type = self::TYPE_OBJECT;
} elseif (count($right->args) === 1 and $fn === 'any') { } elseif (count($right->args) === 1 and $fn === 'any') {
$type = self::TYPE_VAR; $type = self::TYPE_VAR;
if (!$this->hasVar($var)) { if (!$this->hasVar($var)) {
@ -1518,6 +1518,11 @@ class CompilerBase extends \PhpAot\Core\Translator
$this->classes[$this->escapeClass($name)] = $classDef; $this->classes[$this->escapeClass($name)] = $classDef;
} }
protected function addObject(string $name, string $class): void
{
$this->context->objects[$name] = $class;
}
protected function addFunction(string $name, FunctionDef $functionDef): void protected function addFunction(string $name, FunctionDef $functionDef): void
{ {
$this->functions[$this->escapeFunction($name)] = $functionDef; $this->functions[$this->escapeFunction($name)] = $functionDef;
@ -1778,13 +1783,13 @@ class CompilerBase extends \PhpAot\Core\Translator
case 'mixed': case 'mixed':
return self::TYPE_VAR; return self::TYPE_VAR;
case 'self': case 'self':
$this->context->objects[$var] = $this->classDef->getNamespacedName(false); $this->addObject($var, $this->classDef->getNamespacedName(false));
return self::TYPE_OBJECT; return self::TYPE_OBJECT;
case 'resource': case 'resource':
$this->fatalError($param, 'Cannot use `resource` as a parameter type.'); $this->fatalError($param, 'Cannot use `resource` as a parameter type.');
// no break // no break
default: default:
$this->context->objects[$var] = $this->getNamespacedClassName($name); $this->addObject($var, $this->getNamespacedClassName($name));
return self::TYPE_OBJECT; return self::TYPE_OBJECT;
} }
} }
@ -2997,7 +3002,8 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($objectName === 'this_') { if ($objectName === 'this_') {
$nativeProperty = $this->findNativeProperty($object, $propertyName, $this->class, $this->namespace); $nativeProperty = $this->findNativeProperty($object, $propertyName, $this->class, $this->namespace);
} elseif ($this->isTypedObject($objectName)) { } elseif ($this->isTypedObject($objectName)) {
$nativeProperty = $this->findNativeProperty($object, $propertyName, $this->context->objects[$objectName]); $className = $this->getObjectType($objectName);
$nativeProperty = $this->findNativeProperty($object, $propertyName, $className);
} }
if ($nativeProperty) { if ($nativeProperty) {
return $nativeProperty; return $nativeProperty;
@ -4078,8 +4084,8 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($object === 'this_') { if ($object === 'this_') {
$nativeFunc = $this->getNativeName($method, $this->namespace, $this->class); $nativeFunc = $this->getNativeName($method, $this->namespace, $this->class);
$classDef = $this->classDef; $classDef = $this->classDef;
} elseif (isset($this->objects[$object])) { } elseif (isset($this->context->objects[$object])) {
$class = $this->objects[$object]; $class = $this->context->objects[$object];
$nativeFunc = $this->getNativeMethod($expr, $class, $method); $nativeFunc = $this->getNativeMethod($expr, $class, $method);
} }
if ($classDef) { if ($classDef) {

@ -5,14 +5,14 @@
function main() function main()
{ {
ini_set("precision", 17); ini_set("precision", 17);
$rounds = 1_0000_0000; $rounds = std::int(1_0000_0000);
$stop = $rounds + 2; $stop = std::int($rounds + 2);
$begin = microtime(true); $begin = microtime(true);
$x = 1.0; $x = std::float(1.0);
$pi = 1.0; $pi = std::float(1.0);
for ($i = 2; $i <= $stop; $i++) { for ($i = std::int(2); $i <= $stop; $i++) {
$x = -1.0 + 2.0 * ($i & 0x1); $x = -1.0 + 2.0 * ($i & 0x1);
$pi += $x / (2 * $i - 1); $pi += $x / (2 * $i - 1);
} }

@ -1,5 +1,7 @@
--TEST-- --TEST--
Property Property
--SKIPIF--
<?php die('skip: not supported');
--FILE-- --FILE--
<?php <?php
class Worker { class Worker {

Loading…
Cancel
Save