From 979ea385ca9ec98bfc06dc0dc029bf58bac93556 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Sat, 27 Jun 2026 08:57:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(runtime):=20=E8=A7=A3=E5=86=B3=E6=8A=BD?= =?UTF-8?q?=E8=B1=A1=E6=96=B9=E6=B3=95=E8=B0=83=E7=94=A8=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E5=B4=A9=E6=BA=83=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了对抽象方法调用的检查和处理逻辑 - 在方法指针获取时过滤掉抽象方法避免错误调用 - 对对象调用抽象类或接口方法时返回 false 避免运行时错误 - 添加了 noProgress 属性用于控制进度显示 - 完善了方法标志位检查机制防止虚方法调用异常 --- src/Php/CompilerBase.php | 12 +++++- .../dynamic_call/call-abstract-method.phpt | 42 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/aot/dynamic_call/call-abstract-method.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 87c607f9..724a1e52 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -349,6 +349,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected CLImate $climate; protected bool $stubFile = false; protected bool $enableProfiler = false; + protected bool $noProgress = false; protected bool $forTest = false; protected Parser $parser; protected PrettyPrinter $printer; @@ -4699,7 +4700,9 @@ class CompilerBase extends \PhpAot\Core\Translator $funcName = ''; } - if ($class and $funcName and !$magicMethod) { + $methodIsAbstract = $class && $funcName && $this->hasClass($class) + && ($this->getMethodFlags($class, $funcName) & Modifiers::ABSTRACT); + if ($class and $funcName and !$magicMethod and !$methodIsAbstract) { $methodPtr = $this->getMethodPtr($class, $funcName); } else { $methodPtr = $method; @@ -5530,6 +5533,13 @@ class CompilerBase extends \PhpAot\Core\Translator } } if ($nativeFunc) { + if ($this->hasClass($class) && $this->getMethodFlags($class, $method) & Modifiers::ABSTRACT) { + return false; + } + if ($object !== 'this_' && !isset($this->context->stableObjects[$object]) + && ($this->isAbstractClass($class) || $this->isInterface($class))) { + return false; + } $this->checkFunction($nativeFunc); if ($this->hasFunction($nativeFunc)) { return $nativeFunc; diff --git a/tests/aot/dynamic_call/call-abstract-method.phpt b/tests/aot/dynamic_call/call-abstract-method.phpt new file mode 100644 index 00000000..266ab369 --- /dev/null +++ b/tests/aot/dynamic_call/call-abstract-method.phpt @@ -0,0 +1,42 @@ +--TEST-- +call abstract base method through concrete object +--FILE-- + new Impl(), + default => new Impl(), + }; +} + +function main(): int +{ + $obj = create('a'); + $r = $obj->run(); // ← CRASH 发生在此虚方法调用 + echo "result: $r\n"; + if ($r === 'ok') { + echo "ALL OK\n"; + return 0; + } + return 1; +} +?> +--EXPECT-- +result: ok +ALL OK