From dc5c90044beb4c3515cdf1f810f9c9cf4f543672 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Sat, 20 Jun 2026 19:58:34 +0800 Subject: [PATCH] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D$GLOBALS=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=A4=84=E7=90=86=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在CompilerBase.php中为$GLOBALS添加特殊处理逻辑,使用php_globals_array()创建独立副本 - 在FuncCallOptimizer.php中优化函数调用时对$GLOBALS的处理 - 移除Translator.php中$GLOBALS的全局变量初始化代码 - 避免直接操作$GLOABLS符号表的引用计数 - 确保$GLOBALS在各读取位置都通过安全方式访问 --- src/Php/CompilerBase.php | 13 +++++++++++++ src/Php/Optimizer/FuncCallOptimizer.php | 6 +++++- src/Php/Translator.php | 7 ++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 959f1683..a17adf3c 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -669,6 +669,12 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isStdContainer($varName)) { return $varName . '_ref'; } + // $GLOBALS is an INDIRECT to &EG(symbol_table), + // whose refcount MUST NOT be directly manipulated. + // Use php_globals_array() to create a separated copy. + if ($varName === 'GLOBALS') { + return 'php_globals_array()'; + } return $varName; case 'Scalar_MagicConst_File': case 'Scalar_MagicConst_Dir': @@ -3155,6 +3161,9 @@ class CompilerBase extends \PhpAot\Core\Translator } } $expr = $this->parseIdentifier($arg->value); + if ($this->isVarExpr($arg->value) and $arg->value->name === 'GLOBALS') { + return 'php_globals_array()'; + } if ($this->isVarExpr($arg->value) and $this->isStdContainer($arg->value->name)) { return $this->convertArrayExpr($expr . '_ref'); } @@ -5664,6 +5673,10 @@ class CompilerBase extends \PhpAot\Core\Translator } $code .= $this->genLocalVarDecl($this->context->localVars); foreach ($this->context->globalVars as $name => $type) { + // $GLOBALS is handled via php_globals_array() at each read site + if ($name === 'GLOBALS') { + continue; + } $code .= $this->getIndent() . self::TYPE_VAR . ' &' . $name . ' = ' . $this->escapeGlobalVar($name) . ';' . PHP_EOL; } foreach ($this->context->objectProps as $name => $info) { diff --git a/src/Php/Optimizer/FuncCallOptimizer.php b/src/Php/Optimizer/FuncCallOptimizer.php index 2863d24d..f0b9a08d 100644 --- a/src/Php/Optimizer/FuncCallOptimizer.php +++ b/src/Php/Optimizer/FuncCallOptimizer.php @@ -336,7 +336,11 @@ trait FuncCallOptimizer protected function getArg(Node\Expr\FuncCall $expr, int $i): string { - return $this->parseIdentifier($expr->args[$i]->value); + $arg = $expr->args[$i]->value; + if ($this->isVarExpr($arg) and $arg->name === 'GLOBALS') { + return 'php_globals_array()'; + } + return $this->parseIdentifier($arg); } protected function getRefArg(Node\Expr\FuncCall $expr, int $i): string diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 3432cabc..38e01484 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -864,12 +864,9 @@ CODE; $code .= '// global vars ' . PHP_EOL; foreach ($this->globalVars as $name => $type) { if ($name == 'GLOBALS') { - $var = $this->escapeGlobalVar($name); - $code .= 'ZVAL_ARR(&globals_array, &EG(symbol_table));' . PHP_EOL; - $code .= 'ZVAL_INDIRECT(' . $var. '.ptr(), &globals_array);' . PHP_EOL; - } else { - $code .= 'php::initGlobal(' . $this->genCharPtr($name) . ', ' . $this->escapeGlobalVar($name) . ');' . PHP_EOL; + continue; } + $code .= 'php::initGlobal(' . $this->genCharPtr($name) . ', ' . $this->escapeGlobalVar($name) . ');' . PHP_EOL; } $code .= '// static property ' . PHP_EOL;