diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 810b14fd..1b994c03 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -19,7 +19,7 @@ return (new PhpCsFixer\Config()) 'binary_operator_spaces' => ['operators' => ['=' => null, '=>' => null, ]], 'blank_line_after_namespace' => true, 'blank_line_before_statement' => ['statements' => ['declare']], - 'class_attributes_separation' => true, + 'class_attributes_separation' => ['elements' => ['method' => 'one', 'property' => 'only_if_meta']], 'concat_space' => ['spacing' => 'one'], 'constant_case' => ['case' => 'lower'], 'combine_consecutive_unsets' => true, @@ -63,4 +63,4 @@ return (new PhpCsFixer\Config()) ->exclude(['html', 'vendor']) ->in(__DIR__) ) - ->setUsingCache(false); + ->setUsingCache(false); \ No newline at end of file diff --git a/src/Php/ArgInfo.php b/src/Php/ArgInfo.php index fa893aeb..70324c25 100644 --- a/src/Php/ArgInfo.php +++ b/src/Php/ArgInfo.php @@ -11,8 +11,6 @@ namespace PhpAot\Php; class ArgInfo { public string $name; - public string $type; - public string $default = ''; } diff --git a/src/Php/ClassDef.php b/src/Php/ClassDef.php index 61a7ee3c..610c2eba 100644 --- a/src/Php/ClassDef.php +++ b/src/Php/ClassDef.php @@ -24,13 +24,9 @@ class ClassDef extends ClassLikeDef * @var array */ public array $constants = []; - public array $implements = []; - public string $extends = ''; - public bool $requireCtor = false; - public int $flags; public function __construct(string $name, int $flags, string $namespace = '') diff --git a/src/Php/ClassLikeDef.php b/src/Php/ClassLikeDef.php index ca8a1198..77390874 100644 --- a/src/Php/ClassLikeDef.php +++ b/src/Php/ClassLikeDef.php @@ -11,9 +11,7 @@ namespace PhpAot\Php; class ClassLikeDef { public string $name; - public string $namespace; - public string $extends = ''; public function __construct(string $name, string $namespace = '') diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0f743591..51cfa8ce 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -34,27 +34,16 @@ class CompilerBase extends \PhpAot\Core\Translator public const string TYPE_INT = 'php::Int'; public const string TYPE_FLOAT = 'php::Float'; - public const string TYPE_OBJECT = 'php::Object'; - public const string TYPE_ARRAY = 'php::Array'; - public const string TYPE_STR = 'php::Str'; - public const string TYPE_REF = 'php::Ref'; - public const string TYPE_VOID = 'void'; - public const string VALUE_NAN = 'std::numeric_limits::quiet_NaN()'; - public const string VALUE_INF = 'std::numeric_limits::infinity()'; - public const string LITERAL_STRINGS = '_literal_strings'; - - public const string CLASS_ENTRY_MAP = 'class_entry_map'; - + public const string CLASS_MAP = 'class_map'; public const string FUNC_MAP = 'func_map'; - public const string EXPR_VARIABLE = 'Expr_Variable'; public const string EXPR_NEW = 'Expr_New'; @@ -64,32 +53,21 @@ class CompilerBase extends \PhpAot\Core\Translator public const string NAMESPACE_SEPARATOR = '__'; public const string PREFIX = 'php_'; - protected string $phpxDir = '~/workspace/projects/phpx'; - protected string $lang = 'PHP'; - protected string $cppCompiler = 'g++'; - protected array $arguments = []; - protected array $literalStrings = []; - protected int $literalStringIndex = 0; - protected int $tmpVarIndex = 0; - protected int $classIndex = 0; /** * @var array */ protected array $classMap = []; - protected int $funcIndex = 0; - protected array $funcMap = []; - protected array $zendTypeMap = [ 'int' => self::TYPE_INT, 'float' => self::TYPE_FLOAT, @@ -100,7 +78,6 @@ class CompilerBase extends \PhpAot\Core\Translator 'object' => self::TYPE_OBJECT, 'mixed' => self::TYPE_VAR, ]; - protected array $globalHeaders = [ 'phpx.h', 'phpx_helper.h', @@ -108,68 +85,44 @@ class CompilerBase extends \PhpAot\Core\Translator 'php_func_decl.h', 'php_global_var_decl.h', ]; - protected array $localHeaders = []; - protected array $nativeFunctions = []; - protected array $internalFunctions = []; - protected array $nativeConstants = []; - protected array $functionDeclInFile = []; - protected array $functionCallInFile = []; - protected array $redoAfterDeclare = []; - protected int $optimizeLevel = 0; - protected string $buildMode = 'bin'; - protected string $cxxflags = ''; - protected string $ldflags = ''; - protected int $floatPrecision = 17; - protected bool $debugInfo = true; - protected bool $noLiteralStrings = false; - protected bool $useCppNamespace = false; - protected string $file; - protected string $dir; /** * 原始值,可能包含 `\\` 多层空间. */ protected string $namespace = ''; - protected string $method = ''; - protected string $function = ''; - protected array $useNamespaces = []; - protected array $useAliases = []; - protected array $useFunctions = []; /** * 原始类名,不包含命名空间. */ protected string $class = ''; - protected string $interface = ''; /** * @var array */ protected array $classes = []; - protected array $interfaces = []; /** @@ -196,16 +149,11 @@ class CompilerBase extends \PhpAot\Core\Translator * @var array */ protected array $classCeList = []; - protected array $classCeInfo = []; - protected FunctionDef $functionDef; - protected ClassDef $classDef; - protected InterfaceDef $interfaceDef; - - protected array $globalVars = [ + protected array $superGlobalVars = [ '_GET' => self::TYPE_ARRAY, '_POST' => self::TYPE_ARRAY, '_COOKIE' => self::TYPE_ARRAY, @@ -213,45 +161,30 @@ class CompilerBase extends \PhpAot\Core\Translator '_FILES' => self::TYPE_ARRAY, '_SESSION' => self::TYPE_ARRAY, '_REQUEST' => self::TYPE_ARRAY, - 'GLOBALS' => self::TYPE_ARRAY, - 'argc' => self::TYPE_INT, - 'argv' => self::TYPE_ARRAY, ]; + protected array $globalVars = []; /** * @var array */ protected array $objects = []; - protected array $localVars = []; - protected array $objectWrappers = []; - protected bool $strictTypes = false; - protected string $rootPath; - protected string $buildDir; - protected int $debugLine = 0; - protected CLImate $climate; - protected array $beforeStmtLines = []; - protected array $afterStmtLines = []; - protected bool $inLoop = false; /** * 赋值表达式的左值,写操作,右值为读操作. */ protected bool $inAssignExpr = false; - protected bool $stubFile = false; - protected bool $enableProfiler = false; - protected Parser $parser; public function __construct(string $rootPath) @@ -301,6 +234,14 @@ class CompilerBase extends \PhpAot\Core\Translator return isset($this->objects[$object]); } + protected function isSuperGlobal(string $var): bool + { + if (isset($this->superGlobalVars[$var])) { + return true; + } + return false; + } + public function parseExpr(mixed $expr) { $type = $expr->getType(); @@ -669,7 +610,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->classMap[$className] = $id; } - return 'php_get_class_entry(' . $id . ', "' . $this->escapeString($className) . '")'; + return 'php_get_class(' . $id . ', "' . $this->escapeString($className) . '")'; } protected function getFuncPtr(string $funcName): string @@ -677,11 +618,10 @@ class CompilerBase extends \PhpAot\Core\Translator if (isset($this->funcMap[$funcName])) { $id = $this->funcMap[$funcName]; } else { - $id = $this->funcIndex++; + $id = $this->funcIndex++; $this->funcMap[$funcName] = $id; } - - return 'php_get_func(' . $id . ', "' . $this->escapeString($funcName) . '")'; + return $id . ', "' . $this->escapeString($funcName) . '"'; } protected function parseFunctionDeclaration(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef @@ -800,7 +740,9 @@ class CompilerBase extends \PhpAot\Core\Translator if (is_object($expr->name) and $this->isVarExpr($expr->name)) { $this->fatalError($expr, 'The `$$` syntax is not supported'); } - + if ($this->isSuperGlobal($expr->name) and !$this->hasGlobalVar($expr->name)) { + $this->addGlobalVar($expr->name, $this->superGlobalVars[$expr->name]); + } return $this->escapeVarName($expr->name); case 'Name': case 'VarLikeIdentifier': @@ -1710,9 +1652,15 @@ class CompilerBase extends \PhpAot\Core\Translator } } - protected function parseArrayDimFetch($node, bool $write): string + protected function parseArrayDimFetch(Node\Expr\ArrayDimFetch $node, bool $write): string { $var = $this->parseIdentifier($node->var); + if ($this->isVarExpr($node->var) and $var === 'GLOBALS') { + if ($node->dim === null) { + $this->fatalError($node, 'Cannot use [] for GLOBALS'); + } + return 'php::global(' . $this->parseIdentifier($node->dim) . ')'; + } if ($node->dim === null) { if (!$write) { $this->fatalError($node, 'Cannot use [] for reading'); @@ -1781,6 +1729,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseFuncCall(Node\Expr\FuncCall $expr, bool $silent = false): string { + $call = ''; if ($this->isVarExpr($expr->name)) { $fn = $this->parseIdentifier($expr->name); $name = ''; @@ -1798,6 +1747,7 @@ class CompilerBase extends \PhpAot\Core\Translator return $code; } $fn = $this->getFuncPtr($name); + $call = $silent ? 'CALL_SILENT' : 'CALL'; } else { $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_VAR); @@ -1805,8 +1755,9 @@ class CompilerBase extends \PhpAot\Core\Translator $fn = $tmpVar; $name = ''; } - $call = $silent ? 'php::silentCall' : 'php::call'; - + if (!$call) { + $call = $silent ? 'php::silentCall' : 'php::call'; + } if (empty($expr->args)) { return $call . '(' . $fn . ')'; } @@ -2307,6 +2258,11 @@ class CompilerBase extends \PhpAot\Core\Translator return strtolower($class); } + protected function escapeFileName(string $file): string + { + return str_replace('-', '_', $file); + } + protected function unescapeVarName(string $name): string { return str_replace('_php__var__', '', $name); diff --git a/src/Php/ConstantDef.php b/src/Php/ConstantDef.php index 946d810a..dd546193 100644 --- a/src/Php/ConstantDef.php +++ b/src/Php/ConstantDef.php @@ -11,11 +11,8 @@ namespace PhpAot\Php; class ConstantDef { public string $name; - public string $type; - public string $flags; - public string $value; public function __construct(string $name, string $flags, string $type, string $value) diff --git a/src/Php/Encryptor.php b/src/Php/Encryptor.php index 513a6460..859ef5fe 100644 --- a/src/Php/Encryptor.php +++ b/src/Php/Encryptor.php @@ -13,21 +13,14 @@ use PhpParser\PrettyPrinter\Standard; class Encryptor extends \PhpAot\Core\Translator { protected array $stmts; - protected string $phpxDir = '~/workspace/phpx'; - protected string $lang = 'PHP'; - protected array $typeMap = []; - protected array $headers = [ 'phpx.h', ]; - protected array $encodeMap; - protected array $decodeMap; - protected array $constants; public function __construct(array $stmts) diff --git a/src/Php/Extractor.php b/src/Php/Extractor.php index 7307ae3f..513d3de6 100644 --- a/src/Php/Extractor.php +++ b/src/Php/Extractor.php @@ -11,7 +11,6 @@ namespace PhpAot\Php; class Extractor { private string $ctagsPath = 'ctags'; - private bool $isUniversalCtags = false; public function __construct() diff --git a/src/Php/FileScanner.php b/src/Php/FileScanner.php index e6c6feb1..33957414 100644 --- a/src/Php/FileScanner.php +++ b/src/Php/FileScanner.php @@ -13,9 +13,7 @@ class FileScanner public const array PHP_EXT = ['php']; public const array CPP_EXT = ['cpp', 'cxx', 'cc']; - private string $directory; - private array $excludePatterns; public function __construct(string $directory) diff --git a/src/Php/FileSorter.php b/src/Php/FileSorter.php index 6727a7a5..5bc4dfc9 100644 --- a/src/Php/FileSorter.php +++ b/src/Php/FileSorter.php @@ -11,7 +11,6 @@ namespace PhpAot\Php; class FileSorter { private array $functionDeclInFile; - private array $functionCallInFile; public function __construct(array $functionDeclInFile, array $functionCallInFile) diff --git a/src/Php/FunctionDef.php b/src/Php/FunctionDef.php index ec33a0ba..51adf5b8 100644 --- a/src/Php/FunctionDef.php +++ b/src/Php/FunctionDef.php @@ -11,18 +11,14 @@ namespace PhpAot\Php; class FunctionDef { public string $name; - public string $returnType; /** * @var array */ public array $argInfoList = []; - public int $argCountRequired = 0; - public string $params = ''; - public bool $method = false; public function __construct(string $name, string $returnType) diff --git a/src/Php/MethodDef.php b/src/Php/MethodDef.php index f3de54db..a1ff7a0b 100644 --- a/src/Php/MethodDef.php +++ b/src/Php/MethodDef.php @@ -11,9 +11,7 @@ namespace PhpAot\Php; class MethodDef { public int $flags; - public string $name; - public FunctionDef $functionDef; public function __construct(int $flags, string $name, FunctionDef $def) diff --git a/src/Php/PropertyDef.php b/src/Php/PropertyDef.php index 246e77f1..6a4c1605 100644 --- a/src/Php/PropertyDef.php +++ b/src/Php/PropertyDef.php @@ -13,11 +13,8 @@ use PhpParser\Modifiers; class PropertyDef { public string $name; - public string $type; - public int $flags; - public ?string $default = null; public function __construct(string $name, int $flags, string $type, ?string $default = null) diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 93369f46..dcf374dc 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -18,15 +18,10 @@ use Symfony\Component\Yaml\Yaml; class Translator extends Preprocessor { use MagicMethodDetector; - protected string $targetName = 'app'; - protected bool $verbose = false; - protected array $phpSrcFiles = []; - protected array $argInfoHeaderFiles = []; - protected array $unsupportedFunctions = [ 'compact', 'extract', @@ -204,8 +199,8 @@ class Translator extends Preprocessor $literalStringsCount = count($this->literalStrings); $lines[] = 'extern php::Var ' . self::LITERAL_STRINGS . '[' . $literalStringsCount . '];' . PHP_EOL; - $classEntryCount = count($this->classMap); - $lines[] = 'extern zend_class_entry *' . self::PREFIX . self::CLASS_ENTRY_MAP . '[' . $classEntryCount . '];' . PHP_EOL; + $classCount = count($this->classMap); + $lines[] = 'extern zend_class_entry *' . self::PREFIX . self::CLASS_MAP . '[' . $classCount . '];' . PHP_EOL; $funcCount = count($this->funcMap); $lines[] = 'extern zend_function *' . self::PREFIX . self::FUNC_MAP . '[' . $funcCount . '];' . PHP_EOL; @@ -300,8 +295,10 @@ class Translator extends Preprocessor $code .= 'extern ' . $constant->type . ' ' . $name . ';' . PHP_EOL; } - $code .= 'extern zend_class_entry *php_get_class_entry(int class_id, const char *class_name);' . PHP_EOL; + $code .= 'extern zend_class_entry *php_get_class(int class_id, const char *class_name);' . PHP_EOL; $code .= 'extern zend_function *php_get_func(int func_id, const char *func_name);' . PHP_EOL; + $code .= '#define CALL(id, name, args) php::call(php_get_func(id, name), args)' . PHP_EOL; + $code .= '#define CALL_SILENT(id, name, args) php::silentCall(php_get_func(id, name), args)' . PHP_EOL; $this->writeFile($file, $code); } @@ -314,6 +311,7 @@ class Translator extends Preprocessor public function getArgInfoHeaderFile(string $stubFilenameWithoutExtension, bool $relative = false): string { $basename = self::PREFIX . basename($stubFilenameWithoutExtension); + $basename = $this->escapeFileName($basename); $absPath = $this->getIncludeDir() . "/{$basename}_arginfo.h"; if ($relative) { return ltrim($this->removeCommonPrefix($this->getIncludeDir(), $absPath), '/'); diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index 4b6a406e..cada7074 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -22,16 +22,16 @@ zend_class_entry * ; // class entry -zend_class_entry *classMap) . ']' ?>; +zend_class_entry *classMap) . ']' ?>; // func zend_function *funcMap) . ']' ?>; -zend_class_entry *php_get_class_entry(int class_id, const char *class_name) { - if (UNEXPECTED([class_id] == nullptr)) { - [class_id] = php::getClassEntrySafe(class_name); +zend_class_entry *php_get_class(int class_id, const char *class_name) { + if (UNEXPECTED([class_id] == nullptr)) { + [class_id] = php::getClassEntrySafe(class_name); } - return [class_id]; + return [class_id]; } zend_function *php_get_func(int func_id, const char *func_name) { @@ -104,7 +104,7 @@ foreach ($this->nativeConstants as $name => $constant): globalVars as $name => $type): ?> - = php::global(""); + php::initGlobal("", ); // property offset @@ -124,6 +124,7 @@ void php_app_clean() { foreach ($this->globalVars as $name => $type) : ?> .unset(); + php::unsetGlobal(""); nativeConstants as $name => $constant): diff --git a/tests/aot/global-vars.phpt b/tests/aot/global-vars.phpt new file mode 100644 index 00000000..75c3a922 --- /dev/null +++ b/tests/aot/global-vars.phpt @@ -0,0 +1,17 @@ +--TEST-- +global vars +--FILE-- + +--EXPECTF-- +int(100) +int(100) +string(5) "array" +int(%d)