diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index ffbc2adb..ba290961 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -276,14 +276,14 @@ class CompilerBase extends \PhpAot\Core\Translator return implode(self::NAMESPACE_SEPARATOR, array_reverse($names)); } - protected function parseFunctionDeclaration(string $name, Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef + protected function parseFunctionDeclaration(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef { $returnType = $v->returnType ? $this->getTypeFromZendType($this->parseIdentifier($v->returnType)) : self::TYPE_VOID; // .stub 存根定义 C++ Native 函数,必须设置返回值类型 if ($returnType === self::TYPE_VOID && $this->stubFile) { - throw new Exception('No return type for ' . $name); + throw new Exception('No return type for ' . $v->name); } - $functionDef = new FunctionDef($name, $returnType); + $functionDef = new FunctionDef($this->parseIdentifier($v->name), $returnType); $this->functionDef = $functionDef; $this->parseParams($v->params, $functionDef); return $functionDef; @@ -297,7 +297,7 @@ class CompilerBase extends \PhpAot\Core\Translator if (isset($this->nativeFunctions[$name])) { $this->functionDef = $this->nativeFunctions[$name]; } else { - $this->nativeFunctions[$name] = $this->parseFunctionDeclaration($name, $v); + $this->nativeFunctions[$name] = $this->parseFunctionDeclaration($v); if (isset($this->redoAfterDeclare[$name])) { unset($this->redoAfterDeclare[$name]); $this->climate->cyan('Received redo request, retrying...'); diff --git a/src/Php/Constants.php b/src/Php/Constants.php index d3e0dd88..fd787523 100644 --- a/src/Php/Constants.php +++ b/src/Php/Constants.php @@ -35,6 +35,7 @@ class Constants 'new', 'null', 'var', + 'char', 'or', 'and', 'private', diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 970d8139..71218e95 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -140,7 +140,7 @@ class Preprocessor extends CompilerBase { $name = $this->getFunctionName($v); if ($this->stubFile) { - $this->nativeFunctions[$name] = $this->parseFunctionDeclaration($name, $v); + $this->nativeFunctions[$name] = $this->parseFunctionDeclaration($v); } else { $this->functionDeclInFile[$name] = $this->file; } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index dad53cf8..fbcff471 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -657,15 +657,11 @@ class Translator extends Preprocessor return $code; } - protected function genMethodWrapper(ClassDef $classDef, MethodDef $methodDef): string + protected function genWrapperFunctionArgs(string $fn, FunctionDef $functionDef): string { - $name = $classDef->getNamespacedName(); - $cppCode = 'ZEND_METHOD(' . $name . ', ' . $methodDef->name . '){' . PHP_EOL; - $cppCode .= $this->getIndent() . self::TYPE_OBJECT . ' this_(&execute_data->This);' . PHP_EOL; - $fn = self::PREFIX . $this->getNativeMethodName($classDef, $methodDef); - + $cppCode = ''; $callParams = ''; - foreach ($methodDef->functionDef->argInfoList as $k => $argInfo) { + foreach ($functionDef->argInfoList as $k => $argInfo) { if ($argInfo->default) { $argExpr = 'php::getCallArg(' . $k . ', ' . $argInfo->default . ')'; } else { @@ -675,9 +671,14 @@ class Translator extends Preprocessor $cppCode .= $this->getIndent() . $argInfo->type . ' arg_' . $argInfo->name . ' = ' . $expr . ';' . PHP_EOL; $callParams .= 'arg_' . $argInfo->name . ','; } - $callParams = $methodDef->functionDef->argInfoList ? 'this_, ' . rtrim($callParams, ',') : 'this_'; - if ($methodDef->getReturnType() !== self::TYPE_VOID) { + if ($functionDef->method) { + $callParams = $functionDef->argInfoList ? 'this_, ' . rtrim($callParams, ',') : 'this_'; + } else { + $callParams = $functionDef->argInfoList ? rtrim($callParams, ',') : ''; + } + + if ($functionDef->returnType !== self::TYPE_VOID) { $cppCode .= $this->getIndent() . 'auto retval = ' . $fn . '(' . $callParams . ');' . PHP_EOL; $cppCode .= $this->getIndent() . 'php::move(retval, return_value);' . PHP_EOL; } else { @@ -688,33 +689,22 @@ class Translator extends Preprocessor return $cppCode; } - private function genFunctionWrapper(FunctionDef $functionDef) + protected function genMethodWrapper(ClassDef $classDef, MethodDef $methodDef): string + { + $name = $classDef->getNamespacedName(); + $cppCode = 'ZEND_METHOD(' . $name . ', ' . $methodDef->name . '){' . PHP_EOL; + $cppCode .= $this->getIndent() . self::TYPE_OBJECT . ' this_(&execute_data->This);' . PHP_EOL; + $fn = self::PREFIX . $this->getNativeMethodName($classDef, $methodDef); + $cppCode .= $this->genWrapperFunctionArgs($fn, $methodDef->functionDef); + return $cppCode; + } + + private function genFunctionWrapper(FunctionDef $functionDef): string { $name = $functionDef->name; $cppCode = 'ZEND_FUNCTION(' . $name . '){' . PHP_EOL; $fn = self::PREFIX . $this->getNativeName($functionDef->name); - - $callParams = ''; - foreach ($functionDef->argInfoList as $k => $argInfo) { - if ($argInfo->default) { - $argExpr = 'php::getCallArg(' . $k . ', ' . $argInfo->default . ')'; - } else { - $argExpr = 'php::getCallArg(' . $k . ')'; - } - $expr = $this->convertExprFromType($argInfo->type, $argExpr); - $cppCode .= $this->getIndent() . $argInfo->type . ' arg_' . $argInfo->name . ' = ' . $expr . ';' . PHP_EOL; - $callParams .= 'arg_' . $argInfo->name . ','; - } - $callParams = $functionDef->argInfoList ? rtrim($callParams, ',') : ''; - - if ($functionDef->returnType !== self::TYPE_VOID) { - $cppCode .= $this->getIndent() . 'auto retval = ' . $fn . '(' . $callParams . ');' . PHP_EOL; - $cppCode .= $this->getIndent() . 'php::move(retval, return_value);' . PHP_EOL; - } else { - $cppCode .= $this->getIndent() . $fn . '(' . $callParams . ');' . PHP_EOL; - } - $cppCode .= '}' . PHP_EOL . PHP_EOL; - + $cppCode .= $this->genWrapperFunctionArgs($fn, $functionDef); return $cppCode; }