From ca4a34204ce4c14ac8f06c2c3ad68213dbf87e57 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Sun, 8 Feb 2026 19:01:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(compiler):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=20main=20=E5=87=BD=E6=95=B0=E7=9A=84=E7=89=B9=E6=AE=8A?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=92=8C=E5=8F=82=E6=95=B0=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在编译器中实现 main 函数的特殊处理逻辑 - 验证 main 函数的参数必须为 (int $argc, array $argv) 格式 - 确保 main 函数返回类型为 void - 在扩展模板中添加 main 函数调用支持 - 根据构建模式条件编译模块入口点 - 移除旧的静态 main 函数调用方式 - 更新示例项目以使用正确的 main 函数签名 --- examples/project/main.php | 3 ++- src/Php/CompilerBase.php | 24 ++++++++++++++++++++++-- src/cpp/main.cc | 1 - src/template/extension.cc.php | 15 ++++++++++++--- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/examples/project/main.php b/examples/project/main.php index 9f7e5300..87da44b1 100644 --- a/examples/project/main.php +++ b/examples/project/main.php @@ -1,6 +1,7 @@ returnType && $this->stubFile) { throw new \Exception('No return type for ' . $v->name); } + $fnName = $this->parseIdentifier($v->name); $returnType = $v->returnType ? $this->getTypeFromZendType($this->parseIdentifier($v->returnType)) : self::TYPE_VOID; - $functionDef = new FunctionDef($this->parseIdentifier($v->name), $returnType); + $functionDef = new FunctionDef($fnName, $returnType); $this->functionDef = $functionDef; + $this->parseParams($v->params, $functionDef); + // main 函数,返回值必须为 void 类型,参数必须为空或者 argc, argv 两个参数 + if (!$this->class and !$this->namespace and $fnName === 'main') { + if (count($v->params) > 0) { + if (count($v->params) != 2) { + $this->fatalError($v, 'The parameters of the main function must be `(int $argc, array $argv)`.'); + } + if ($returnType !== self::TYPE_VOID) { + $this->fatalError($v, 'main function must return void'); + } + if ($functionDef->argInfoList[0]->type !== self::TYPE_VAR and $functionDef->argInfoList[0]->type !== self::TYPE_INT) { + $this->fatalError($v, 'The first parameter of the main function must be of type `int`.'); + } + if ($functionDef->argInfoList[1]->type !== self::TYPE_VAR and $functionDef->argInfoList[1]->type !== self::TYPE_ARRAY) { + $this->fatalError($v, 'The second parameter of the main function must be of type `array`.'); + } + } + } + return $functionDef; } @@ -1504,7 +1524,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($link) { $cmd .= ' -shared'; } else { - $cmd .= ' -fPIC -D BUILD_PHP_EXTENSION=1'; + $cmd .= ' -fPIC'; } } diff --git a/src/cpp/main.cc b/src/cpp/main.cc index 70c6aa54..b5e653ac 100644 --- a/src/cpp/main.cc +++ b/src/cpp/main.cc @@ -42,7 +42,6 @@ int main(int cpp_argc, char **cpp_argv) { #endif try { module->request_startup_func(module->type, module->module_number); - php::eval("main();"); } catch (zend_object *e) { rc = EG(exit_status); CG(unclean_shutdown) = 1; diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index 90b6b650..8b761296 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -149,6 +149,15 @@ foreach ($this->nativeConstants as $name => $constant): static PHP_RINIT_FUNCTION(targetName?>) { php::request_init(); php_app_init(); + +buildMode === 'bin'): ?> +functions['main']->argInfoList) == 2): ?> + php::eval("global $argc, $argv; main($argc, $argv);"); + + php::eval("main();"); + + + return SUCCESS; } @@ -171,10 +180,10 @@ zend_module_entry targetName?>_module_entry = { STANDARD_MODULE_PROPERTIES, }; -#ifdef BUILD_PHP_EXTENSION +buildMode === 'ext'): ?> ZEND_GET_MODULE(targetName?>); -#else + zend_module_entry *get_module() { return &targetName ?>_module_entry; } -#endif + \ No newline at end of file