From 26a0439f42827fccb4102e49d5a71cf15c26dcf7 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Fri, 3 Apr 2026 18:12:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E4=BC=98=E5=8C=96=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E8=B0=83=E7=94=A8=E5=B9=B6=E6=B7=BB=E5=8A=A0=E7=B1=BB?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E6=80=A7=E6=A3=80=E6=9F=A5=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现 class_exists 函数的静态分析优化,直接返回已知类的存在性 - 添加 get_class 函数支持,为类型化对象生成字符指针 - 优化 function_exists 函数检查逻辑,提前处理原生函数 - 添加 get_class 测试用例验证功能 - 更新基准测试代码,添加 class_exists 性能测试 - 移除未使用的宏定义,优化常量定义方式 --- examples/micro_bench.php | 9 +++++---- src/Php/FuncCallOptimizer.php | 20 +++++++++++++++++++- tests/aot/functions/get_class.phpt | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 tests/aot/functions/get_class.phpt diff --git a/examples/micro_bench.php b/examples/micro_bench.php index 325b6a1b..a14d629c 100644 --- a/examples/micro_bench.php +++ b/examples/micro_bench.php @@ -18,8 +18,10 @@ function hallo2() { function simpleicall($n) { - for ($i = 0; $i < $n; $i++) - $ret = function_exists('hallo'); + for ($i = 0; $i < $n; $i++) { +// $ret = function_exists('hallo'); + $ret = class_exists('Foo2'); + } } class Foo { @@ -169,7 +171,6 @@ function create_object($n) { function read_const($n) { for ($i = 0; $i < $n; ++$i) { -// $x = TEST; $x = TEST_CONST_2; } } @@ -280,11 +281,11 @@ function total() const N = 5000000; const TEST = null; +const TEST_CONST_2 = 1999; function main() { global $total, $last_time, $g_var; - define('TEST_CONST_2', 1999); $g_var = 0; $t0 = $t = start_test(); empty_loop(N); diff --git a/src/Php/FuncCallOptimizer.php b/src/Php/FuncCallOptimizer.php index 8490e90e..b3787be2 100644 --- a/src/Php/FuncCallOptimizer.php +++ b/src/Php/FuncCallOptimizer.php @@ -109,6 +109,18 @@ trait FuncCallOptimizer if ($name === 'function_exists') { return $this->genFunctionExists($name, $expr); } + if ($name === 'class_exists') { + $className = $expr->args[0]->value; + if ($this->isScalarString($className) and $this->hasClass($className->value)) { + return 'true'; + } + } + if ($name === 'get_class') { + $object = $expr->args[0]->value; + if ($this->isVarExpr($object) and $this->isTypedObject($object->name)) { + return $this->genCharPtr($this->getObjectType($object->name)); + } + } return false; } @@ -128,9 +140,15 @@ trait FuncCallOptimizer { $funcName = $expr->args[0]->value; if ($this->isScalarString($funcName)) { - $funcName = $this->getLiteralString(strtolower(trim($funcName->value, '\\'))); + $nameLower = strtolower(trim($funcName->value, '\\')); + if ($this->findNativeFunction($nameLower)) { + return 'true'; + } + $funcName = $this->getLiteralString($nameLower); return 'php::fn::function_exists(' . $funcName . ', true)'; } return 'php::fn::function_exists(' . $this->parseIdentifier($funcName) . ')'; } + + } diff --git a/tests/aot/functions/get_class.phpt b/tests/aot/functions/get_class.phpt new file mode 100644 index 00000000..141e8683 --- /dev/null +++ b/tests/aot/functions/get_class.phpt @@ -0,0 +1,17 @@ +--TEST-- +class const 001 +--FILE-- + +--EXPECT-- +string(6) "Worker" \ No newline at end of file