diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index c6a1bcce..0a2aa8f2 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1320,21 +1320,11 @@ class CompilerBase extends \PhpAot\Core\Translator } elseif ($this->isStaticCall($right) and $this->isIdExpr($right->name)) { $class = $this->parseIdentifier($right->class); if ($class === 'std') { - $func = $this->parseIdentifier($right->name); - $type = match ($func) { - 'int' => self::TYPE_INT, - 'float' => self::TYPE_FLOAT, - 'bool' => self::TYPE_BOOL, - default => '', - }; - // Native 类型 - if ($type) { - if (!$this->hasVar($var)) { - $this->addLocalVar($var, $type); - } - $expr = $this->parseExpr($right->args[0]->value); - return $var . ' = ' . $this->convertExprFromType($type, $expr); + $valueExpr = $this->parseStdCall($right); + if (!$this->hasVar($var)) { + $this->addLocalVar($var, $right->getAttribute('nativeType')); } + return $var . ' = ' . $valueExpr; } } elseif ($this->isVarExpr($right)) { $rightVar = $this->parseIdentifier($right); @@ -4095,6 +4085,8 @@ class CompilerBase extends \PhpAot\Core\Translator $self = true; } elseif ($class === 'parent') { return $this->parseParentMethodCall($expr); + } elseif ($class === 'std') { + return $this->parseStdCall($expr); } $class = $this->getNamespacedClassName($class); @@ -4658,6 +4650,24 @@ class CompilerBase extends \PhpAot\Core\Translator return $code . "{$obj}.updateArrayProperty({$propName}, {$dim}, {$value})"; } + protected function parseStdCall(Expr\StaticCall $expr): string + { + $func = $this->parseIdentifier($expr->name); + $type = match ($func) { + 'int' => self::TYPE_INT, + 'float' => self::TYPE_FLOAT, + 'bool' => self::TYPE_BOOL, + default => '', + }; + if ($type) { + $expr->setAttribute('nativeType', $type); + $valueExpr = $this->parseExpr($expr->args[0]->value); + return $this->convertExprFromType($type, $valueExpr); + } else { + $this->fatalError($expr, 'Unknown std method: ' . $func); + } + } + protected function parseParentMethodCall(Expr\StaticCall $expr): string { $methodStr = $this->classDef->name . '::' . $this->parseIdentifier($expr->name); diff --git a/src/gen_stub.php b/src/gen_stub.php index 9527117c..a79db747 100755 --- a/src/gen_stub.php +++ b/src/gen_stub.php @@ -3119,24 +3119,22 @@ class StringBuilder { return $result; } $include = self::PHP_80_KNOWN; - switch ($minPhp) { - case PHP_85_VERSION_ID: - $include = array_merge($include, self::PHP_85_KNOWN); - // Intentional fall through - - case PHP_84_VERSION_ID: - $include = array_merge($include, self::PHP_84_KNOWN); - // Intentional fall through - - case PHP_83_VERSION_ID: - case PHP_82_VERSION_ID: - $include = array_merge($include, self::PHP_82_KNOWN); - // Intentional fall through - - case PHP_81_VERSION_ID: - $include = array_merge($include, self::PHP_81_KNOWN); - break; + + $versions = [ + PHP_85_VERSION_ID => self::PHP_85_KNOWN, + PHP_84_VERSION_ID => self::PHP_84_KNOWN, + PHP_82_VERSION_ID => self::PHP_82_KNOWN, // 8.3 合并到 8.2 + PHP_81_VERSION_ID => self::PHP_81_KNOWN, + ]; + + krsort($versions); + + foreach ($versions as $versionId => $knownItems) { + if ($minPhp >= $versionId) { + $include = array_merge($include, $knownItems); + } } + if (array_key_exists($content, $include)) { $knownStr = $include[$content]; return [ @@ -4279,10 +4277,11 @@ class FileInfo { */ public function getAllFuncInfos(): iterable { + $allFuncInfos = []; foreach ($this->classInfos as $classInfo) { - yield from $classInfo->funcInfos; + $allFuncInfos = array_merge($allFuncInfos, $classInfo->funcInfos); } - yield from $this->funcInfos; + return array_merge($allFuncInfos, $this->funcInfos); } /** @return array */ diff --git a/tests/aot/operator/assignop_bitwiseor.phpt b/tests/aot/operator/assignop_bitwiseor.phpt index c6faa284..66370d25 100644 --- a/tests/aot/operator/assignop_bitwiseor.phpt +++ b/tests/aot/operator/assignop_bitwiseor.phpt @@ -7,7 +7,12 @@ function main() $a = 100; $a |= 16; var_dump($a); + + $b = std::int(200); + $b |= std::int(32); + var_dump($b); } ?> --EXPECT-- int(116) +int(232)