refactor(php): 重构函数调用和错误抑制处理逻辑

- 将 isExitExpr 方法中的 Node\Stmt 类型检查更改为 Node\Stmt\Expression
- 移除 getFuncPtr 方法中的 macro 参数及相关逻辑
- 移除 parseFuncCall 方法中的 silent 参数及静默调用相关代码
- 统一函数调用都使用 php::call 方式
- 重写 parseErrorSuppress 方法,使用 error_reporting 函数控制错误报告级别
- 简化调试信息相关的代码生成逻辑
- 删除 cpp_aot_helper.h 中的 CALL 和 CALL_SILENT 内联函数定义
- 更新所有 getFuncPtr 调用移除第二个参数
pull/1/head
韩天峰 5 months ago
parent 52b1effffb
commit 52319ccd03
  1. 12
      examples/silentCall.php
  2. 2
      src/Php/AstNodeType.php
  3. 36
      src/Php/CompilerBase.php
  4. 2
      src/Php/Generator/PlaceHolderGenerator.php
  5. 24
      src/cpp/php_aot_helper.h

@ -1,5 +1,9 @@
<?php <?php
$cache = []; function main()
$key = 'hello'; {
$hello = @$cache[$key]; $cache = [];
var_dump($hello); $key = 'hello';
$hello = @$cache[$key];
var_dump($hello);
var_dump($cache["world"]);
}

@ -124,7 +124,7 @@ trait AstNodeType
protected function isExitExpr(NodeAbstract $expr): bool protected function isExitExpr(NodeAbstract $expr): bool
{ {
if ($expr instanceof Node\Stmt) { if ($expr instanceof Node\Stmt\Expression) {
$expr = $expr->expr; $expr = $expr->expr;
} }
return $expr instanceof Node\Expr\Exit_; return $expr instanceof Node\Expr\Exit_;

@ -744,13 +744,9 @@ class CompilerBase extends \PhpAot\Core\Translator
return $object; return $object;
} }
protected function getFuncPtr(string $funcName, bool $macro = true): string protected function getFuncPtr(string $funcName): string
{ {
$id = $this->getFuncId($funcName); return 'php_get_func(' . $this->getFuncId($funcName) . ', ' . $this->getLiteralString($funcName) . ')';
if ($macro) {
return $id . ', ' . $this->getLiteralString($funcName);
}
return 'php_get_func(' . $id . ', ' . $this->getLiteralString($funcName) . ')';
} }
protected function getMethodPtr(string $class, string $method): string protected function getMethodPtr(string $class, string $method): string
@ -2195,7 +2191,7 @@ class CompilerBase extends \PhpAot\Core\Translator
$this->fatalError($node, 'All execution code must be within a function, found stray code'); $this->fatalError($node, 'All execution code must be within a function, found stray code');
} }
protected function parseFuncCall(Node\Expr\FuncCall $expr, bool $silent = false): string protected function parseFuncCall(Node\Expr\FuncCall $expr): string
{ {
$call = ''; $call = '';
if ($this->isVarExpr($expr->name)) { if ($this->isVarExpr($expr->name)) {
@ -2219,7 +2215,6 @@ class CompilerBase extends \PhpAot\Core\Translator
$placeHolder = $this->identifierToStr($expr->name); $placeHolder = $this->identifierToStr($expr->name);
$fn = $this->getFuncPtr($name); $fn = $this->getFuncPtr($name);
$this->beforeStmtLines[] = '// Func Call: ' . $name . '()'; $this->beforeStmtLines[] = '// Func Call: ' . $name . '()';
$call = $silent ? 'CALL_SILENT' : 'CALL';
} else { } else {
$tmpVar = $this->genTmpVarName(); $tmpVar = $this->genTmpVarName();
$this->addLocalVar($tmpVar, self::TYPE_VAR); $this->addLocalVar($tmpVar, self::TYPE_VAR);
@ -2227,14 +2222,11 @@ class CompilerBase extends \PhpAot\Core\Translator
$placeHolder = $fn = $tmpVar; $placeHolder = $fn = $tmpVar;
$name = ''; $name = '';
} }
if (!$call) {
$call = $silent ? 'php::silentCall' : 'php::call';
}
if (empty($expr->args)) { if (empty($expr->args)) {
return $call . '(' . $fn . ')'; return 'php::call(' . $fn . ')';
} }
try { try {
return $call . '(' . $fn . ', ' . $this->parseCallArgs($expr->args, $name) . ')'; return 'php::call(' . $fn . ', ' . $this->parseCallArgs($expr->args, $name) . ')';
} catch (PlaceHolder) { } catch (PlaceHolder) {
return $this->genPlaceHolder($placeHolder); return $this->genPlaceHolder($placeHolder);
} }
@ -3655,7 +3647,7 @@ class CompilerBase extends \PhpAot\Core\Translator
} }
} }
$ce = $this->getClassEntryPtr($class); $ce = $this->getClassEntryPtr($class);
$fn = $ce . ', ' . $this->getFuncPtr($class . '::' . $method, false); $fn = $ce . ', ' . $this->getFuncPtr($class . '::' . $method);
$placeHolder = $this->genArray($callScope); $placeHolder = $this->genArray($callScope);
} }
$call = 'php::call'; $call = 'php::call';
@ -4018,10 +4010,12 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseErrorSuppress(Node\Expr\ErrorSuppress $expr): string protected function parseErrorSuppress(Node\Expr\ErrorSuppress $expr): string
{ {
if ($expr->expr instanceof Node\Expr\FuncCall) { $tmpVar = $this->genTmpVarName();
return $this->parseFuncCall($expr->expr, true); $this->beforeStmtLines[] = 'auto ' . $tmpVar . ' = EG(error_reporting);';
} $this->beforeStmtLines[] = 'php::call(' . $this->getFuncPtr('error_reporting') . ', {E_FATAL_ERRORS});';
abort($expr); $code = $this->parseExpr($expr->expr);
$this->afterStmtLines[] = 'php::call(' . $this->getFuncPtr('error_reporting') . ', {' . $tmpVar . '});';
return $code;
} }
protected function checkVar(NodeAbstract $node, string $name): void protected function checkVar(NodeAbstract $node, string $name): void
@ -4115,11 +4109,9 @@ class CompilerBase extends \PhpAot\Core\Translator
$code = ''; $code = '';
if ($this->debugInfo) { if ($this->debugInfo) {
if ($stmt) { if ($stmt) {
$code .= 'php::debug_info.php_file = "' . $this->escapeString($this->file) . '";' . PHP_EOL; $code .= 'php::traceDebugInfo("' . $this->escapeString($this->file) . '", ' . $stmt->getLine() . ');' . PHP_EOL;
$code .= 'php::debug_info.php_line = ' . $stmt->getLine() . ';' . PHP_EOL;
$code .= 'php::debug_info.cpp_line = __LINE__;' . PHP_EOL;
} else { } else {
$code .= 'php::debug_info.enable = true;' . PHP_EOL; $code .= 'php::enableDebugInfo();' . PHP_EOL;
} }
} }
return $code; return $code;

@ -13,7 +13,7 @@ trait PlaceHolderGenerator
protected function genPlaceHolder(string $callable): string protected function genPlaceHolder(string $callable): string
{ {
$ce = $this->getClassEntryPtr(\Closure::class); $ce = $this->getClassEntryPtr(\Closure::class);
$fn = $ce . ', ' . $this->getFuncPtr('Closure::fromCallable', false); $fn = $ce . ', ' . $this->getFuncPtr('Closure::fromCallable');
$tmpVar = $this->genTmpVarName(); $tmpVar = $this->genTmpVarName();
if ($this->classDef) { if ($this->classDef) {
$this->beforeStmtLines[] = "auto $tmpVar = php_switch_scope(this_);"; $this->beforeStmtLines[] = "auto $tmpVar = php_switch_scope(this_);";

@ -19,27 +19,3 @@ extern const char *php_get_called_class(php::Object &this_);
extern zend_class_entry *php_get_called_ce(php::Object &this_); extern zend_class_entry *php_get_called_ce(php::Object &this_);
extern php::Scope php_switch_scope(php::Object &this_); extern php::Scope php_switch_scope(php::Object &this_);
extern void php_restore_scope(php::Scope &ori_scope); extern void php_restore_scope(php::Scope &ori_scope);
static inline php::Variant CALL(int func_id, const php::Str &func_name) {
return php::call(php_get_func(func_id, func_name));
}
static inline php::Variant CALL(int func_id, const php::Str &func_name, const php::ArgList &args) {
return php::call(php_get_func(func_id, func_name), args);
}
static inline php::Variant CALL(int func_id, const php::Str &func_name, php::Array &args) {
return php::call(php_get_func(func_id, func_name), args);
}
static inline php::Variant CALL_SILENT(int func_id, const php::Str &func_name) {
return php::silentCall(php_get_func(func_id, func_name));
}
static inline php::Variant CALL_SILENT(int func_id, const php::Str &func_name, const php::ArgList &args) {
return php::silentCall(php_get_func(func_id, func_name), args);
}
static inline php::Variant CALL_SILENT(int func_id, const php::Str &func_name, php::Array &args) {
return php::call(php_get_func(func_id, func_name), args);
}

Loading…
Cancel
Save