feat(compiler): 添加原生静态方法查找和数组维度引用功能

- 新增 getNativeStaticMethod 方法用于查找原生静态方法
- 添加对数字类型变量使用 [] 操作的错误检查
- 实现数组维度获取的引用参数处理逻辑
- 支持静态方法调用时的原生函数优化
- 添加 item-ref 测试用例验证数组引用功能
pull/1/head
韩天峰 7 months ago
parent 8fd83ae8b0
commit 2acc84659a
  1. 40
      src/Php/CompilerBase.php
  2. 46
      tests/aot/item-ref.phpt

@ -1266,6 +1266,18 @@ class CompilerBase extends \PhpAot\Core\Translator
return array_key_exists($name, $this->classes);
}
protected function getNativeStaticMethod(string $class, string $method): string|false
{
if (!$this->hasNativeClass($class)) {
return false;
}
$class = $this->getClassDef($class);
if (!$class->hasMethod($method)) {
return false;
}
return $this->getNativeName($method, $class->name, $class->namespace);
}
protected function getClassDef(string $name): ClassDef
{
$name = trim($name, '\\');
@ -1704,6 +1716,11 @@ class CompilerBase extends \PhpAot\Core\Translator
} else {
$this->fatalError($node->var, "The variable `{$node->var->name}` is undefined");
}
} else {
$type = $this->getVarType($var);
if ($type === self::TYPE_BOOL || $type === self::TYPE_INT || $type === self::TYPE_FLOAT) {
$this->fatalError($node, 'Cannot use [] for numbers');
}
}
if ($this->getVarType($var) === self::TYPE_STR) {
if ($node->dim === null) {
@ -1864,10 +1881,19 @@ class CompilerBase extends \PhpAot\Core\Translator
}
} elseif ($this->isPropertyFetch($arg->value)) {
if ($funcName and Reflection::isReferenceArg($funcName, $i)) {
$obj = $this->parseIdentifier($arg->value->var);
$obj = $this->parseIdentifier($arg->value->var);
$list_args[] = $obj . '.attrRef(' . $this->identifierToStr($arg->value->name) . ')';
continue;
}
} elseif ($this->isArrayDimFetch($arg->value)) {
if ($funcName and Reflection::isReferenceArg($funcName, $i)) {
$obj = $this->parseIdentifier($arg->value->var);
if ($arg->value->dim === null) {
$this->fatalError($arg, 'Array dimension must be a constant expression');
}
$list_args[] = $obj . '.itemRef(' . $this->identifierToStr($arg->value->dim) . ')';
continue;
}
}
// 不支持变长参数展开的语法,例如:array_merge(...$arr)
if ($arg->unpack) {
@ -2916,12 +2942,22 @@ class CompilerBase extends \PhpAot\Core\Translator
$fn = 'php::concat({' . $this->identifierToStr($expr->class) . ', "::", ' . $this->identifierToStr($expr->name) . '})';
} else {
$class = $this->parseIdentifier($expr->class);
$method = $this->parseIdentifier($expr->name);
if ($class === 'self') {
$class = $this->class;
} elseif ($class === 'parent') {
return $this->parseParentMethodCall($expr);
}
$method = $this->parseIdentifier($expr->name);
if ($this->isNameExpr($expr->class) and $this->isIdExpr($expr->name)) {
$nativeFunc = $this->getNativeStaticMethod($class, $method);
$args = $this->parseNativeCallArgs($expr->args, $nativeFunc);
if ($args) {
return self::PREFIX . $nativeFunc . '(php::null_object, ' . $args . ')';
} else {
return self::PREFIX . $nativeFunc . '(php::null_object)';
}
}
$ce = $this->getClassEntryPtr($class);
$fn = $ce . ', ' . $this->getFuncPtr($class . '::' . $method, false);
}

@ -0,0 +1,46 @@
--TEST--
item reference
--FILE--
<?php
$a = [5, 3, 1, 9, 2, 4, 3];
$b = [$a, $a];
sort($b[0]);
var_dump($b);
?>
--EXPECT--
array(2) {
[0]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(3)
[4]=>
int(4)
[5]=>
int(5)
[6]=>
int(9)
}
[1]=>
array(7) {
[0]=>
int(5)
[1]=>
int(3)
[2]=>
int(1)
[3]=>
int(9)
[4]=>
int(2)
[5]=>
int(4)
[6]=>
int(3)
}
}
Loading…
Cancel
Save