diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index cd77c8b8..5dc70b9d 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -143,8 +143,8 @@ class CompilerBase extends \PhpAot\Core\Translator protected array $nativeFunctions = []; protected array $internalFunctions = []; protected array $nativeConstants = []; - protected array $functionDeclInFile = []; - protected array $functionCallInFile = []; + protected array $symbolDeclInFile = []; + protected array $symbolCallInFile = []; protected array $redoAfterDeclare = []; protected array $constData = []; protected int $optimizeLevel = 0; @@ -1600,8 +1600,8 @@ class CompilerBase extends \PhpAot\Core\Translator { // 在预处理阶段检测到函数声明,但是未定义,说明在当前文件,但是顺序错误 // 跳过,稍后再处理 - if (isset($this->functionDeclInFile[$name]) - and $this->functionDeclInFile[$name] === $this->file + if (isset($this->symbolDeclInFile[$name]) + and $this->symbolDeclInFile[$name] === $this->file and !$this->hasNativeFunction($name)) { $this->redoAfterDeclare[$name] = true; throw new Skip(); diff --git a/src/Php/FileSorter.php b/src/Php/FileSorter.php index 5bc4dfc9..829e577f 100644 --- a/src/Php/FileSorter.php +++ b/src/Php/FileSorter.php @@ -10,13 +10,13 @@ namespace PhpAot\Php; class FileSorter { - private array $functionDeclInFile; - private array $functionCallInFile; + private array $symbolDeclInFile; + private array $symbolCallInFile; - public function __construct(array $functionDeclInFile, array $functionCallInFile) + public function __construct(array $symbolDeclInFile, array $symbolCallInFile) { - $this->functionDeclInFile = $functionDeclInFile; - $this->functionCallInFile = $functionCallInFile; + $this->symbolDeclInFile = $symbolDeclInFile; + $this->symbolCallInFile = $symbolCallInFile; } public function sort(): array @@ -65,12 +65,12 @@ class FileSorter { $dependencies = []; - foreach ($this->functionCallInFile as $call) { + foreach ($this->symbolCallInFile as $call) { $callerFile = $call['file']; $functionName = $call['name']; - if (isset($this->functionDeclInFile[$functionName])) { - $declFile = $this->functionDeclInFile[$functionName]; + if (isset($this->symbolDeclInFile[$functionName])) { + $declFile = $this->symbolDeclInFile[$functionName]; if ($callerFile !== $declFile) { if (!isset($dependencies[$callerFile])) { @@ -89,9 +89,9 @@ class FileSorter private function getAllFiles(): array { - $files = array_values($this->functionDeclInFile); + $files = array_values($this->symbolDeclInFile); - foreach ($this->functionCallInFile as $call) { + foreach ($this->symbolCallInFile as $call) { $files[] = $call['file']; } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index d23ac47b..6f0cdd37 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -20,12 +20,12 @@ class Preprocessor extends CompilerBase public function sortFiles(array &$list): void { - foreach ($this->functionCallInFile as $k => $call) { - if (!isset($this->functionDeclInFile[$call['name']])) { - unset($this->functionCallInFile[$k]); + foreach ($this->symbolCallInFile as $k => $call) { + if (!isset($this->symbolDeclInFile[$call['name']])) { + unset($this->symbolCallInFile[$k]); } } - $sorter = new FileSorter($this->functionDeclInFile, $this->functionCallInFile); + $sorter = new FileSorter($this->symbolDeclInFile, $this->symbolCallInFile); $sortedFiles = $sorter->sort(); foreach ($list as $file) { @@ -120,8 +120,8 @@ class Preprocessor extends CompilerBase foreach ($functionCalls as $call) { if ($call->name instanceof Node\Name) { - $name = $call->name->toString(); - $this->functionCallInFile[] = [ + $name = $call->name->toString(); + $this->symbolCallInFile[] = [ 'name' => $name, 'file' => $this->file, 'line' => $call->getLine(), @@ -164,7 +164,7 @@ class Preprocessor extends CompilerBase if ($this->stubFile) { $this->nativeFunctions[$name] = $this->parseFunctionDecl($v); } else { - $this->functionDeclInFile[$name] = $this->file; + $this->symbolDeclInFile[$name] = $this->file; } } @@ -180,11 +180,18 @@ class Preprocessor extends CompilerBase protected function prepareClass(Node\Stmt\Class_|Node\Stmt\Trait_|Node\Stmt\Enum_ $class): string { $this->class = $this->parseIdentifier($class->name); + $fullClassName = $this->getNamespacedClassName($this->class); if (!empty($class->extends)) { $this->parentClass = $this->getParentClass($class->extends); - $fullClassName = $this->getNamespacedClassName($this->class); + $this->symbolCallInFile[] = [ + 'name' => $this->parentClass, + 'file' => $this->file, + 'line' => $class->getLine(), + ]; $this->classExtends[$fullClassName] = $this->parentClass; } + $this->symbolDeclInFile[$fullClassName] = $this->file; + $code = ''; foreach ($class->stmts as $v) { $type = $v->getType(); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 4ce4a7f5..8eeda76b 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -419,6 +419,9 @@ class Translator extends Preprocessor { $code = '#include ' . PHP_EOL; + $literalStringsCount = count($this->literalStrings); + $code .= 'extern ' . self::TYPE_STR . ' ' . self::LITERAL_STRINGS . '[' . $literalStringsCount . '];' . PHP_EOL; + foreach ($this->nativeFunctions as $name => $func) { $code .= 'extern ' . $func->returnType . ' ' . self::PREFIX . $name . '('; $list = [];