feat(compiler): 添加对 main 函数的特殊支持和参数验证

- 在编译器中实现 main 函数的特殊处理逻辑
- 验证 main 函数的参数必须为 (int $argc, array $argv) 格式
- 确保 main 函数返回类型为 void
- 在扩展模板中添加 main 函数调用支持
- 根据构建模式条件编译模块入口点
- 移除旧的静态 main 函数调用方式
- 更新示例项目以使用正确的 main 函数签名
pull/1/head
韩天峰 7 months ago
parent 288021d16c
commit ca4a34204c
  1. 3
      examples/project/main.php
  2. 24
      src/Php/CompilerBase.php
  3. 1
      src/cpp/main.cc
  4. 15
      src/template/extension.cc.php

@ -1,6 +1,7 @@
<?php
function main()
function main($argc, array $argv)
{
var_dump($argc, $argv);
fn1();
$rs = fn_test(199, 189);
$array = [1, 3, 5];

@ -642,11 +642,31 @@ class CompilerBase extends \PhpAot\Core\Translator
if (!$v->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';
}
}

@ -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;

@ -149,6 +149,15 @@ foreach ($this->nativeConstants as $name => $constant):
static PHP_RINIT_FUNCTION(<?=$this->targetName?>) {
php::request_init();
php_app_init();
<?php if ($this->buildMode === 'bin'): ?>
<?php if (count($this->functions['main']->argInfoList) == 2): ?>
php::eval("global $argc, $argv; main($argc, $argv);");
<?php else:?>
php::eval("main();");
<?php endif; ?>
<?php endif; ?>
return SUCCESS;
}
@ -171,10 +180,10 @@ zend_module_entry <?=$this->targetName?>_module_entry = {
STANDARD_MODULE_PROPERTIES,
};
#ifdef BUILD_PHP_EXTENSION
<?php if ($this->buildMode === 'ext'): ?>
ZEND_GET_MODULE(<?=$this->targetName?>);
#else
<?php else: ?>
zend_module_entry *<?= self::PREFIX . 'embed_' ?>get_module() {
return &<?= $this->targetName ?>_module_entry;
}
#endif
<?php endif; ?>
Loading…
Cancel
Save