code format

pull/1/head
韩天峰 6 months ago
parent 70eccf59fc
commit b6d64407f3
  1. 8
      src/Core/Translator.php
  2. 44
      src/Php/CompilerBase.php
  3. 7
      src/Php/Exception/PlaceHolder.php
  4. 19
      src/Php/Generator/ClosureGenerator.php
  5. 9
      src/Php/Generator/PlaceHolderGenerator.php
  6. 6
      src/Php/Generator/Utils.php
  7. 3
      src/Php/Preprocessor.php
  8. 26
      src/Php/Reflection.php
  9. 5
      src/Php/Translator.php
  10. 147
      src/Python/Translator.php
  11. 7
      src/config/compiler_options.php
  12. 11
      src/functions.php
  13. 187
      src/template/extension.cc.php

@ -1,12 +1,18 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Core;
abstract class Translator
{
public string $mode = 'cli';
protected int $indentLevel = 0;
protected string $indentStr = "\t";
public string $mode = 'cli';
protected string $lang;
public function setMode($mode): void

@ -219,7 +219,7 @@ class CompilerBase extends \PhpAot\Core\Translator
{
$this->rootPath = $rootPath;
$this->parser = (new ParserFactory())->createForNewestSupportedVersion();
$this->printer = new PrettyPrinter\Standard;
$this->printer = new PrettyPrinter\Standard();
$this->setBuildDir($rootPath . '/build');
$climate = new CLImate();
$this->climate = $climate;
@ -452,6 +452,7 @@ class CompilerBase extends \PhpAot\Core\Translator
case 'Expr_Yield':
case 'Expr_YieldFrom':
$this->fatalError($expr, 'The `' . $type . '` is not supported');
// no break
default:
abort($expr);
}
@ -724,14 +725,13 @@ class CompilerBase extends \PhpAot\Core\Translator
return 'php_get_method(' . $funcId . ', ' . $this->getLiteralString($method) . ', ' . $classId . ', ' . $this->getLiteralString($class) . ')';
}
protected function parseTypeDecl(NodeAbstract|null $type): string
protected function parseTypeDecl(?NodeAbstract $type): string
{
// 联合类型暂时不支持,使用 var 类型代替
if ($type instanceof Node\UnionType or $type instanceof NullableType) {
if ($type instanceof UnionType or $type instanceof NullableType) {
return self::TYPE_VAR;
} else {
return $type ? $this->getTypeFromZendType($this->parseIdentifier($type)) : self::TYPE_VOID;
}
return $type ? $this->getTypeFromZendType($this->parseIdentifier($type)) : self::TYPE_VOID;
}
protected function parseFunctionDecl(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef
@ -1057,6 +1057,7 @@ class CompilerBase extends \PhpAot\Core\Translator
break;
case 'Stmt_Class':
$this->fatalError($v, 'Cannot declare class in function');
// no break
default:
abort($v);
}
@ -1351,9 +1352,8 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($v->expr === null) {
if ($this->functionDef->returnType === self::TYPE_VOID and !$this->inClosure) {
return 'return;';
} else {
return 'return ' . self::VALUE_NULL . ';';
}
return 'return ' . self::VALUE_NULL . ';';
}
// 实际函数的返回值
$type = $this->detectExprType($v->expr);
@ -1984,7 +1984,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function foundStrayCode(Node $node): never
{
$this->fatalError($node, "All execution code must be within a function, found stray code");
$this->fatalError($node, 'All execution code must be within a function, found stray code');
}
protected function parseFuncCall(Node\Expr\FuncCall $expr, bool $silent = false): string
@ -2044,7 +2044,7 @@ class CompilerBase extends \PhpAot\Core\Translator
throw new PlaceHolder();
}
if ($arg->name) {
foreach($functionDef->argInfoList as $k => $argInfo) {
foreach ($functionDef->argInfoList as $k => $argInfo) {
if ($argInfo->name === $arg->name->name) {
$args[$k] = $arg;
$hasNamedArg = true;
@ -2070,9 +2070,8 @@ class CompilerBase extends \PhpAot\Core\Translator
}
$argList[] = '{' . implode(', ', $list_vargs) . '}';
break;
} else {
$argList[] = $this->getTypeConvertedArg($arg, $argInfo);
}
$argList[] = $this->getTypeConvertedArg($arg, $argInfo);
}
return implode(', ', $argList);
@ -3012,9 +3011,9 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($var->default) {
$initState = self::STATIC_VAR . $varName . '_initialized';
$initCode = $this->getIndent() . 'static bool ' . $initState . ' = false;';
$initCode .= $this->getIndent() . "if (!$initState) { \n";
$initCode .= $this->getIndent() . "if (!{$initState}) { \n";
$this->indentLevel++;
$initCode .= $this->getIndent() . "$initState = true;\n";
$initCode .= $this->getIndent() . "{$initState} = true;\n";
$initCode .= $this->getIndent() . $this->getStaticVarName($varName) . ' = ' . $this->parseIdentifier($var->default) . ';';
$this->indentLevel--;
$initCode .= $this->getIndent() . '}';
@ -3116,8 +3115,6 @@ class CompilerBase extends \PhpAot\Core\Translator
/**
* 左值只能为变量、数组、对象属性、对象静态属性
* @param NodeAbstract $expr
* @return void
*/
protected function checkLeftValue(NodeAbstract $expr): void
{
@ -3353,8 +3350,9 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($this->isTypedObject($var)) {
$class = $this->getObjectType($var);
goto _do_call;
} elseif ($this->getVarType($var) == self::TYPE_OBJECT) {
$fn = 'php::concat({' . $var . '.getClassName()' . ', "::", ' . $this->identifierToStr($expr->name) . '})';
}
if ($this->getVarType($var) == self::TYPE_OBJECT) {
$fn = 'php::concat({' . $var . '.getClassName(), "::", ' . $this->identifierToStr($expr->name) . '})';
} else {
$fn = 'php::concat({' . $this->identifierToStr($expr->class) . ', "::", ' . $this->identifierToStr($expr->name) . '})';
}
@ -3381,9 +3379,8 @@ class CompilerBase extends \PhpAot\Core\Translator
}
if ($args) {
return self::PREFIX . $nativeFunc . '(php::null_object, ' . $args . ')';
} else {
return self::PREFIX . $nativeFunc . '(php::null_object)';
}
return self::PREFIX . $nativeFunc . '(php::null_object)';
}
}
$ce = $this->getClassEntryPtr($class);
@ -3441,7 +3438,8 @@ class CompilerBase extends \PhpAot\Core\Translator
$propertyDef = $classDef->getProperty($property);
if ($propertyDef->isPublic()) {
return self::PREFIX . $this->getPropertyOffset($property, $classDef->name, $classDef->namespace);
} elseif ($propertyDef->isProtected()) {
}
if ($propertyDef->isProtected()) {
if ($scope) {
return self::PREFIX . $this->getPropertyOffset($property, $classDef->name, $classDef->namespace);
}
@ -3861,13 +3859,13 @@ class CompilerBase extends \PhpAot\Core\Translator
{
if ($this->functionDef->returnType === self::TYPE_VOID) {
return '';
} elseif ($this->functionDef->returnType === self::TYPE_INT
}
if ($this->functionDef->returnType === self::TYPE_INT
or $this->functionDef->returnType === self::TYPE_FLOAT
or $this->functionDef->returnType === self::TYPE_BOOL) {
return $this->getIndent() . 'return 0;';
} else {
return $this->getIndent() . 'return ' . self::VALUE_NULL . ';';
}
return $this->getIndent() . 'return ' . self::VALUE_NULL . ';';
}
protected function genEmbeddedCode(NodeAbstract $stmt): string

@ -1,8 +1,13 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php\Exception;
class PlaceHolder extends \RuntimeException
{
}

@ -1,19 +1,19 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php\Generator;
use PhpParser\Node\Expr\ArrowFunction;
use PhpParser\NodeAbstract;
trait ClosureGenerator
{
/**
* @param NodeAbstract $expr
* @param array $params
* @param callable $bodyGenCb
* @param array $uses
* @param $useCurrentScope bool 直接使用当前作用域,C++ 函数将使用 & 捕获所有闭包变量
* @return string
*/
protected function genClosure(NodeAbstract $expr, array $params, callable $bodyGenCb, array $uses = [], bool $useCurrentScope = false): string
{
@ -78,17 +78,16 @@ trait ClosureGenerator
$this->errorUndefinedVariable($useItem->var);
}
if ($useItem->byRef) {
$useVars [] = $this->convertToRef($useItem->var);
$useVars[] = $this->convertToRef($useItem->var);
} else {
$useVars [] = $var;
$useVars[] = $var;
}
}
}
if ($this->methodDef) {
return 'php::newClosure(' . $tmpVar . ', { ' . implode(', ', $useVars) . ' }, this_)';
} else {
return 'php::newClosure(' . $tmpVar . ', { ' . implode(', ', $useVars) . ' })';
}
return 'php::newClosure(' . $tmpVar . ', { ' . implode(', ', $useVars) . ' })';
}
}

@ -1,10 +1,13 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php\Generator;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\NodeAbstract;
trait PlaceHolderGenerator
{
protected function genPlaceHolder(string $callable): string

@ -1,4 +1,10 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php\Generator;

@ -108,6 +108,7 @@ class Preprocessor extends CompilerBase
break;
case 'Stmt_Expression':
$this->foundStrayCode($v);
// no break
default:
$this->fatalError($v, 'Unsupported statement: ' . $type);
}
@ -148,6 +149,7 @@ class Preprocessor extends CompilerBase
break;
case 'Stmt_Expression':
$this->foundStrayCode($v2);
// no break
default:
abort($v2);
}
@ -183,6 +185,7 @@ class Preprocessor extends CompilerBase
break;
case 'Stmt_Expression':
$this->foundStrayCode($v);
// no break
default:
abort($v);
}

@ -8,23 +8,17 @@
namespace PhpAot\Php;
use ReflectionClass;
use ReflectionException;
use ReflectionFunction;
use ReflectionParameter;
use ReflectionUnionType;
class Reflection
{
private static array $functions = [];
private static array $classes = [];
public static function getFunction(string $fn): ?ReflectionFunction
public static function getFunction(string $fn): ?\ReflectionFunction
{
if (!isset(self::$functions[$fn])) {
try {
$ref = new ReflectionFunction($fn);
} catch (ReflectionException $e) {
$ref = new \ReflectionFunction($fn);
} catch (\ReflectionException $e) {
return null;
}
self::$functions[$fn] = $ref;
@ -33,12 +27,12 @@ class Reflection
return self::$functions[$fn];
}
public static function getClass(string $className): ?ReflectionClass
public static function getClass(string $className): ?\ReflectionClass
{
if (!isset(self::$classes[$className])) {
try {
$ref = new ReflectionClass($className);
} catch (ReflectionException $e) {
$ref = new \ReflectionClass($className);
} catch (\ReflectionException $e) {
return null;
}
self::$classes[$className] = $ref;
@ -57,14 +51,14 @@ class Reflection
if (!$returnType) {
return null;
}
if ($returnType instanceof ReflectionUnionType) {
if ($returnType instanceof \ReflectionUnionType) {
return null;
}
return $returnType->getName();
}
public static function getFunctionParameter(string $fn, int $index): ?ReflectionParameter
public static function getFunctionParameter(string $fn, int $index): ?\ReflectionParameter
{
$func = self::getFunction($fn);
if (!$func) {
@ -78,7 +72,7 @@ class Reflection
return $args[$index];
}
public static function getClassMethodParameter(string $className, string $fn, int $index): ?ReflectionParameter
public static function getClassMethodParameter(string $className, string $fn, int $index): ?\ReflectionParameter
{
$classRef = self::getClass($className);
if (!$classRef) {
@ -87,7 +81,7 @@ class Reflection
try {
$method = $classRef->getMethod($fn);
} catch (ReflectionException $e) {
} catch (\ReflectionException $e) {
return null;
}

@ -334,9 +334,8 @@ class Translator extends Preprocessor
public function getArgInfoStubFilename(string $stubFile): string
{
$rs = str_replace([".stub.php", '.php'], "", $stubFile);
$rs = str_replace('-', '_', $rs);
return $rs;
$rs = str_replace(['.stub.php', '.php'], '', $stubFile);
return str_replace('-', '_', $rs);
}
public function getArgInfoHeaderFile(string $stubFilenameWithoutExtension, bool $relative = false): string

@ -1,13 +1,19 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Python;
class Translator extends \PhpAot\Core\Translator
{
protected string $lang = 'Python';
private array $keywords = ['abs', 'aiter', 'all', 'anext', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip'];
private array $keywordsMap = [];
private array $definedFunctions = [];
protected string $lang = 'Python';
private array $builtinTypes = [
'ArithmeticError',
'AssertionError',
@ -39,7 +45,7 @@ class Translator extends \PhpAot\Core\Translator
'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning',
'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError'
'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError',
];
public function __construct()
@ -95,14 +101,15 @@ class Translator extends \PhpAot\Core\Translator
$id = $fn->id;
if (isset($this->keywordsMap[$id])) {
return 'PyCore::' . $id;
} elseif (isset($this->definedFunctions[$id])) {
}
if (isset($this->definedFunctions[$id])) {
return $id;
} elseif (isset($this->builtinTypes[$id])) {
}
if (isset($this->builtinTypes[$id])) {
return '$builtins->' . $id;
} else {
return '$' . $id;
}
// no break
return '$' . $id;
case 'Attribute':
return $this->parseAttribute($fn->value) . '->' . $fn->attr;
default:
@ -129,41 +136,45 @@ class Translator extends \PhpAot\Core\Translator
}
if (empty($args_list)) {
return "$fn()";
} else {
return "$fn(" . implode(', ', $args_list) . ")";
return "{$fn}()";
}
return "{$fn}(" . implode(', ', $args_list) . ')';
}
public static function valueToRepr($v, $python = false)
{
if (is_string($v)) {
$v = str_replace(
["\\", "\n", "\r", "\t", "\v", "\x00", "\""],
["\\\\", "\\n", "\\r", "\\t", "\\v", "\\x00", "\\\""],
['\\', "\n", "\r", "\t", "\v", "\x00", '"'],
['\\\\', '\\n', '\\r', '\\t', '\\v', '\\x00', '\\"'],
$v
);
return "\"$v\"";
} elseif ($v === []) {
return "\"{$v}\"";
}
if ($v === []) {
return '[]';
} elseif (is_numeric($v)) {
}
if (is_numeric($v)) {
if ($python) {
if (is_infinite($v)) {
return "float('inf')";
} elseif (is_nan($v)) {
}
if (is_nan($v)) {
return "float('nan')";
}
}
return strval($v);
} elseif (is_bool($v)) {
}
if (is_bool($v)) {
return $python ? ($v ? 'True' : 'False') : ($v ? 'true' : 'false');
} elseif (is_null($v)) {
}
if (is_null($v)) {
return $python ? 'None' : 'null';
} elseif (is_array($v)) {
}
if (is_array($v)) {
return var_export($v, true);
} else {
return $python ? 'None' : 'null';
}
return $python ? 'None' : 'null';
}
public function parseConstant($value): string
@ -249,16 +260,17 @@ class Translator extends \PhpAot\Core\Translator
{
if ($slice->_type == 'Constant') {
return $this->parseConstant($slice);
} elseif ($slice->_type === 'Tuple') {
}
if ($slice->_type === 'Tuple') {
return $this->parseTuple($slice);
} elseif ($slice->_type === 'Slice') {
}
if ($slice->_type === 'Slice') {
$_args[] = $slice->lower ? $this->parseTarget($slice->lower) : 'null';
$_args[] = $slice->upper ? $this->parseTarget($slice->upper) : 'null';
$_args[] = $slice->step ? $this->parseTarget($slice->step) : 'null';
return 'PyCore::slice(' . implode(', ', $_args) . ')';
} else {
abort($slice);
}
abort($slice);
}
public function parseImportFrom($node): string
@ -268,7 +280,7 @@ class Translator extends \PhpAot\Core\Translator
foreach ($node->names as $name) {
$type = $name->name;
$as = empty($name->asname) ? $type : $name->asname;
$imports[] = "\$$as = PyCore::import('$module')->$type";
$imports[] = "\${$as} = PyCore::import('{$module}')->{$type}";
}
return implode(';' . PHP_EOL, $imports);
@ -280,7 +292,7 @@ class Translator extends \PhpAot\Core\Translator
foreach ($node->names as $name) {
$module = $name->name;
$as = empty($name->asname) ? $module : $name->asname;
$out .= $this->getIndent() . "\$$as = PyCore::import('$module');\n";
$out .= $this->getIndent() . "\${$as} = PyCore::import('{$module}');\n";
}
return $out;
}
@ -348,10 +360,9 @@ class Translator extends \PhpAot\Core\Translator
case 'Expr':
if (is_string($node->value->value)) {
return '/** ' . $node->value->value . ' */' . PHP_EOL;
} else {
return $this->parseValue($node->value) . ';';
}
// no break
return $this->parseValue($node->value) . ';';
default:
return $this->parseValue($node->value) . ';';
}
@ -468,16 +479,15 @@ class Translator extends \PhpAot\Core\Translator
$op = $node->ctx->_type;
$value = $this->parseValue($node->value);
if ($node->ctx->_type == 'Store') {
return $value. '[' . $this->parseSlice($node->slice) . '] = $__value';
} elseif ($op == 'Del') {
return $value . '[' . $this->parseSlice($node->slice) . '] = $__value';
}
if ($op == 'Del') {
return 'unset(' . $value . '[' . $this->parseSlice($node->slice) . '])';
} else {
}
return $value . '[' . $this->parseSlice($node->slice) . ']';
}
} else {
abort($node);
}
}
public function parseFor($node)
{
@ -502,13 +512,36 @@ class Translator extends \PhpAot\Core\Translator
$fn = PHP_EOL . $this->getIndent() . 'function ' . $name . '(' . $args . ') {' . PHP_EOL;
$this->indentLevel++;
$fn .= $this->parseBody($node->body) . PHP_EOL;
;
$this->indentLevel--;
$fn .= $this->getIndent() . '}' . PHP_EOL . PHP_EOL;
return $fn;
}
public function parseBody($tree): string
{
$lines = [];
foreach ($tree as $node) {
$this->parseLine($node, $lines);
}
foreach ($lines as &$line) {
$line = $this->getIndent() . $line;
}
return implode(PHP_EOL, $lines);
}
public function convert($tree): void
{
$this->prepare($tree);
$output = '<?php' . PHP_EOL;
$output .= '$operator = PyCore::import("operator");' . PHP_EOL;
$output .= '$builtins = PyCore::import("builtins");' . PHP_EOL;
$output .= $this->parseBody($tree->body);
echo $output;
echo PHP_EOL;
}
private function addLine($line, array &$lines)
{
if ($this->mode == 'cli' && STEP) {
@ -528,9 +561,9 @@ class Translator extends \PhpAot\Core\Translator
$value = $this->parseValue($node->value);
if ($node->targets[0]->_type == 'Subscript') {
$this->addLine('$__value = ' . $value . ';', $lines);
$line = "$target;";
$line = "{$target};";
} else {
$line = "$target = $value;";
$line = "{$target} = {$value};";
}
break;
case 'AugAssign':
@ -610,29 +643,6 @@ class Translator extends \PhpAot\Core\Translator
$this->addLine($line, $lines);
}
public function parseBody($tree): string
{
$lines = [];
foreach ($tree as $node) {
$this->parseLine($node, $lines);
}
foreach ($lines as &$line) {
$line = $this->getIndent() . $line;
}
return implode(PHP_EOL, $lines);
}
public function convert($tree): void
{
$this->prepare($tree);
$output = '<?php' . PHP_EOL;
$output .= '$operator = PyCore::import("operator");' . PHP_EOL;
$output .= '$builtins = PyCore::import("builtins");' . PHP_EOL;
$output .= $this->parseBody($tree->body);
echo $output;
echo PHP_EOL;
}
private function parseGenerators($generators, $recipient, &$captures)
{
$captures = [];
@ -686,9 +696,8 @@ class Translator extends \PhpAot\Core\Translator
$op_str = $this->parseOp($op);
if ($op_str) {
return $left . ' ' . $op_str . '= ' . $right . ';';
} else {
return $left . ' = $operator->' . strtolower($op) . '(' . $left . ' , ' . $right . ');';
}
return $left . ' = $operator->' . strtolower($op) . '(' . $left . ' , ' . $right . ');';
}
private function parseBinOp($value)
@ -699,9 +708,8 @@ class Translator extends \PhpAot\Core\Translator
$op_str = $this->parseOp($op);
if ($op_str) {
return $left . ' ' . $op_str . ' ' . $right;
} else {
return '$operator->' . strtolower($op) . '(' . $left . ' , ' . $right . ')';
}
return '$operator->' . strtolower($op) . '(' . $left . ' , ' . $right . ')';
}
private function parseJoinedStr($value)
@ -738,7 +746,7 @@ class Translator extends \PhpAot\Core\Translator
$call = $this->parseCall($call);
$target = empty($target) ? '$__' : $this->parseTarget($target);
$code .= $target . '__object = ' . $call . ';' . PHP_EOL;
;
$code .= $target . ' = ' . $target . '__object->__enter__();' . PHP_EOL;
$this->indentLevel++;
$finally_code .= $this->getIndent() . $target . '__object->__exit__(null, null, null);' . PHP_EOL;
@ -782,7 +790,6 @@ class Translator extends \PhpAot\Core\Translator
return 'new PyDict(' . $code . '])';
}
private function parseBoolOp($value)
{
switch ($value->op->_type) {
@ -948,11 +955,11 @@ class Translator extends \PhpAot\Core\Translator
$format = $value->format_spec->values[0]->value;
if ($format[0] == '.' and $format[-1] == 'f') {
return 'round(' . $expr . ', ' . substr($format, 1, strlen($format) - 2) . ')';
} elseif (str_contains($format, '%')) {
}
if (str_contains($format, '%')) {
return $expr . '->strftime("' . $format . '")';
} else {
throw new \RuntimeException("Unsupported format: $format");
}
throw new \RuntimeException("Unsupported format: {$format}");
} else {
return $expr;
}

@ -1,4 +1,11 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
return [
'optimize' => [
'prefix' => 'O',

@ -1,11 +1,17 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
use PhpAot\Core\Translator;
use PhpAot\Php\Exception\Unsupported;
function abort($v)
{
/**
/*
* @var $translator Translator
*/
global $translator;
@ -38,10 +44,9 @@ function if_not_empty_debug($if_expr, $v)
}
}
function debug()
{
foreach(func_get_args() as $arg) {
foreach (func_get_args() as $arg) {
var_dump($arg);
}
debug_print_backtrace();

@ -1,115 +1,116 @@
<?php
/**
* @var $this Translator
* @var Translator $this
*/
use PhpAot\Php\Translator;
echo $this->genIncludeHeaderFiles();
?>
// global vars
<?php
// 全局变量只能是 var 类型
foreach ($this->globalVars as $name => $type):
?>
<?= Translator::TYPE_VAR ?> <?= $name ?>;
<?php endforeach; ?>
foreach ($this->globalVars as $name => $type) {
?>
<?php echo Translator::TYPE_VAR; ?> <?php echo $name; ?>;
<?php } ?>
// class register functions
<?php
foreach ($this->classCeList as $ce):
?>
zend_class_entry * <?= $ce ?>;
<?php endforeach; ?>
foreach ($this->classCeList as $ce) {
?>
zend_class_entry * <?php echo $ce; ?>;
<?php } ?>
// class entry
zend_class_entry *<?= Translator::PREFIX . Translator::CLASS_MAP . '[' . count($this->classMap) . ']' ?>;
zend_class_entry *<?php echo Translator::PREFIX . Translator::CLASS_MAP . '[' . count($this->classMap) . ']'; ?>;
// func
zend_function *<?= Translator::PREFIX . Translator::FUNC_MAP . '[' . count($this->funcMap) . ']' ?>;
zend_function *<?php echo Translator::PREFIX . Translator::FUNC_MAP . '[' . count($this->funcMap) . ']'; ?>;
zend_class_entry *php_get_class(int class_id, const php::String &class_name) {
if (UNEXPECTED(<?= Translator::PREFIX . Translator::CLASS_MAP ?>[class_id] == nullptr)) {
<?= Translator::PREFIX . Translator::CLASS_MAP ?>[class_id] = php::getClassEntrySafe(class_name);
if (UNEXPECTED(<?php echo Translator::PREFIX . Translator::CLASS_MAP; ?>[class_id] == nullptr)) {
<?php echo Translator::PREFIX . Translator::CLASS_MAP; ?>[class_id] = php::getClassEntrySafe(class_name);
}
return <?= Translator::PREFIX . Translator::CLASS_MAP ?>[class_id];
return <?php echo Translator::PREFIX . Translator::CLASS_MAP; ?>[class_id];
}
zend_function *php_get_func(int func_id, const php::String &func_name) {
if (UNEXPECTED(<?= Translator::PREFIX . Translator::FUNC_MAP ?>[func_id] == nullptr)) {
<?= Translator::PREFIX . Translator::FUNC_MAP ?>[func_id] = php::getFunction(func_name);
if (UNEXPECTED(<?php echo Translator::PREFIX . Translator::FUNC_MAP; ?>[func_id] == nullptr)) {
<?php echo Translator::PREFIX . Translator::FUNC_MAP; ?>[func_id] = php::getFunction(func_name);
}
return <?= Translator::PREFIX . Translator::FUNC_MAP ?>[func_id];
return <?php echo Translator::PREFIX . Translator::FUNC_MAP; ?>[func_id];
}
zend_function *php_get_method(int func_id, const php::Str &method_name, int class_id, const php::Str &class_name) {
if (UNEXPECTED(<?= Translator::PREFIX . Translator::FUNC_MAP ?>[func_id] == nullptr)) {
if (UNEXPECTED(<?php echo Translator::PREFIX . Translator::FUNC_MAP; ?>[func_id] == nullptr)) {
auto ce = php_get_class(class_id, class_name);
<?= Translator::PREFIX . Translator::FUNC_MAP ?>[func_id] = php::getMethod(ce, method_name);
<?php echo Translator::PREFIX . Translator::FUNC_MAP; ?>[func_id] = php::getMethod(ce, method_name);
}
return <?= Translator::PREFIX . Translator::FUNC_MAP ?>[func_id];
return <?php echo Translator::PREFIX . Translator::FUNC_MAP; ?>[func_id];
}
// literal strings
php::Str <?=Translator::LITERAL_STRINGS?>[] = {
php::Str <?php echo Translator::LITERAL_STRINGS; ?>[] = {
<?php
foreach ($this->literalStrings as $str => $index):
?>
php::String{ZEND_STRL("<?=$this->escapeString($str)?>"), true},
<?php endforeach; ?>
foreach ($this->literalStrings as $str => $index) {
?>
php::String{ZEND_STRL("<?php echo $this->escapeString($str); ?>"), true},
<?php } ?>
};
// constants
<?php
foreach ($this->nativeConstants as $name => $const):
?>
<?=$const->type?> <?=$name?>;
<?php endforeach; ?>
foreach ($this->nativeConstants as $name => $const) {
?>
<?php echo $const->type; ?> <?php echo $name; ?>;
<?php } ?>
// property offset
<?php
foreach ($this->classes as $classDef):
foreach ($classDef->properties as $propertyDef):
?>
uint32_t <?=Translator::PREFIX . $this->getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace)?>;
foreach ($this->classes as $classDef) {
foreach ($classDef->properties as $propertyDef) {
?>
uint32_t <?php echo Translator::PREFIX . $this->getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace); ?>;
<?php
endforeach;
endforeach;
}
}
?>
// clang-format off
static const zend_function_entry ext_functions[] = {
<?php
foreach ($this->functions as $functionDef):
foreach ($this->functions as $functionDef) {
if ($this->buildMode === 'ext' and $functionDef->name === 'main') {
continue;
}
$zif_name = $this->escapeZendFnName($functionDef->getNamespacedName());
?>
<?php if ($functionDef->namespace): ?>
ZEND_NAMED_FE("<?=$this->escapeString($functionDef->getNamespacedName())?>", ZEND_FN(<?= $zif_name ?>), arginfo_<?=$zif_name?>)
<?php else: ?>
ZEND_FE(<?=$zif_name?>, arginfo_<?=$zif_name?>)
<?php endif; ?>
<?php endforeach;?>
?>
<?php if ($functionDef->namespace) { ?>
ZEND_NAMED_FE("<?php echo $this->escapeString($functionDef->getNamespacedName()); ?>", ZEND_FN(<?php echo $zif_name; ?>), arginfo_<?php echo $zif_name; ?>)
<?php } else { ?>
ZEND_FE(<?php echo $zif_name; ?>, arginfo_<?php echo $zif_name; ?>)
<?php } ?>
<?php }?>
ZEND_FE_END
};
// clang-format on
PHP_MINIT_FUNCTION(<?=$this->getModuleName()?>) {
PHP_MINIT_FUNCTION(<?php echo $this->getModuleName(); ?>) {
// class/interface class entries
<?php
foreach ($this->classCeList as $ce):
foreach ($this->classCeList as $ce) {
$info = $this->classCeInfo[$ce] ?? $this->getInternalCeInfo($ce);
?>
<?=$ce?> = <?= $info['func'] ?>(<?= $info['args'] ?>);
<?php endforeach; ?>
?>
<?php echo $ce; ?> = <?php echo $info['func']; ?>(<?php echo $info['args']; ?>);
<?php } ?>
// register symbols
<?php
foreach ($this->registerSymbols as $registerSymbolFn):
?>
<?= $registerSymbolFn ?>(module_number);
<?php endforeach; ?>
foreach ($this->registerSymbols as $registerSymbolFn) {
?>
<?php echo $registerSymbolFn; ?>(module_number);
<?php } ?>
return SUCCESS;
}
@ -117,86 +118,86 @@ foreach ($this->registerSymbols as $registerSymbolFn):
void php_app_init() {
// register constants
<?php
foreach ($this->nativeConstants as $name => $const):
?>
<?=$name?> = <?= $const->value ?>;
php::define("<?=$this->escapeString($const->name)?>", <?= $name ?>);
<?php endforeach; ?>
foreach ($this->nativeConstants as $name => $const) {
?>
<?php echo $name; ?> = <?php echo $const->value; ?>;
php::define("<?php echo $this->escapeString($const->name); ?>", <?php echo $name; ?>);
<?php } ?>
// global vars
<?php
foreach ($this->globalVars as $name => $type):
?>
php::initGlobal("<?=$name?>", <?= $name ?>);
<?php endforeach; ?>
foreach ($this->globalVars as $name => $type) {
?>
php::initGlobal("<?php echo $name; ?>", <?php echo $name; ?>);
<?php } ?>
// property offset
<?php
foreach ($this->classes as $classDef):
foreach ($classDef->properties as $propertyDef):
foreach ($this->classes as $classDef) {
foreach ($classDef->properties as $propertyDef) {
?>
<?=Translator::PREFIX . $this->getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace)?> = php::getPropertyOffset("<?=$classDef->getNamespacedName(false)?>", "<?=$propertyDef->name?>");
<?php echo Translator::PREFIX . $this->getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace); ?> = php::getPropertyOffset("<?php echo $classDef->getNamespacedName(false); ?>", "<?php echo $propertyDef->name; ?>");
<?php
endforeach;
endforeach;
}
}
?>
}
void php_app_clean() {
<?php
foreach ($this->globalVars as $name => $type) :
?>
<?= $name ?>.unset();
php::unsetGlobal("<?=$name?>");
<?php endforeach; ?>
foreach ($this->globalVars as $name => $type) {
?>
<?php echo $name; ?>.unset();
php::unsetGlobal("<?php echo $name; ?>");
<?php } ?>
<?php
foreach ($this->nativeConstants as $name => $const):
foreach ($this->nativeConstants as $name => $const) {
if ($const->type !== Translator::TYPE_VAR) {
continue;
}
?>
<?= $name ?>.unset();
<?php endforeach; ?>
?>
<?php echo $name; ?>.unset();
<?php } ?>
}
PHP_RINIT_FUNCTION(<?=$this->getModuleName()?>) {
PHP_RINIT_FUNCTION(<?php echo $this->getModuleName(); ?>) {
php::request_init();
php_app_init();
<?php if ($this->buildMode === 'bin'): ?>
<?php if (count($this->functions['main']->argInfoList) == 2): ?>
<?php if ($this->buildMode === 'bin') { ?>
<?php if (count($this->functions['main']->argInfoList) == 2) { ?>
php::eval("global $argc, $argv; main($argc, $argv);");
<?php else:?>
<?php } else { ?>
php::eval("main();");
<?php endif; ?>
<?php endif; ?>
<?php } ?>
<?php } ?>
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(<?=$this->getModuleName()?>) {
PHP_RSHUTDOWN_FUNCTION(<?php echo $this->getModuleName(); ?>) {
php_app_clean();
php::request_shutdown();
return SUCCESS;
}
zend_module_entry <?=$this->getModuleName()?>_module_entry = {
zend_module_entry <?php echo $this->getModuleName(); ?>_module_entry = {
STANDARD_MODULE_HEADER,
"<?=$this->getModuleName()?>",
"<?php echo $this->getModuleName(); ?>",
ext_functions,
PHP_MINIT(<?=$this->getModuleName()?>),
PHP_MINIT(<?php echo $this->getModuleName(); ?>),
nullptr,
PHP_RINIT(<?=$this->getModuleName()?>),
PHP_RSHUTDOWN(<?=$this->getModuleName()?>),
PHP_RINIT(<?php echo $this->getModuleName(); ?>),
PHP_RSHUTDOWN(<?php echo $this->getModuleName(); ?>),
nullptr,
nullptr,
STANDARD_MODULE_PROPERTIES,
};
<?php if ($this->buildMode === 'ext'): ?>
ZEND_GET_MODULE(<?=$this->getModuleName()?>);
<?php else: ?>
zend_module_entry *<?= Translator::PREFIX . 'embed_' ?>get_module() {
return &<?= $this->getModuleName() ?>_module_entry;
<?php if ($this->buildMode === 'ext') { ?>
ZEND_GET_MODULE(<?php echo $this->getModuleName(); ?>);
<?php } else { ?>
zend_module_entry *<?php echo Translator::PREFIX . 'embed_'; ?>get_module() {
return &<?php echo $this->getModuleName(); ?>_module_entry;
}
<?php endif; ?>
<?php } ?>
Loading…
Cancel
Save