fix(runtime): 解决抽象方法调用导致的崩溃问题

- 添加了对抽象方法调用的检查和处理逻辑
- 在方法指针获取时过滤掉抽象方法避免错误调用
- 对对象调用抽象类或接口方法时返回 false 避免运行时错误
- 添加了 noProgress 属性用于控制进度显示
- 完善了方法标志位检查机制防止虚方法调用异常
pull/3/head
韩天峰 2 months ago
parent 0360a51104
commit 979ea385ca
  1. 12
      src/Php/CompilerBase.php
  2. 42
      tests/aot/dynamic_call/call-abstract-method.phpt

@ -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;

@ -0,0 +1,42 @@
--TEST--
call abstract base method through concrete object
--FILE--
<?php
use native_types;
abstract class Base
{
abstract public function run(): string;
}
class Impl extends Base
{
public function run(): string
{
return 'ok';
}
}
function create(string $type): Base
{
return match ($type) {
'a' => 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
Loading…
Cancel
Save